如何使用ExecutorService修复程序?

时间:2015-05-06 17:28:58

标签: java executorservice

所以,我是Java的新手。

我编写了相对简单的程序,它可以处理大量文件。

速度很慢,我希望运行的线程多于一个。有了StackOverflow社区的帮助,我做了类似的事情:

public class FileProcessor {
    public static void main(String[] args)
    {
        // run 5 threads
        ExecutorService executor = Executors.newFixedThreadPool(5);
        int i;

        // get first and last file ID to process
        int start = Integer.parseInt(args[0]);
        int end = Integer.parseInt(args[1]);

        for (i = start; i < end; i++)
        {
            final int finalId = i; // final necessary in anonymous class
            executor.submit(new Runnable() 
            {
                public void run() 
                {
                    processFile(finalId);
                }
            });
        }
    }

    public static void processFile(int id)
    {
        //doing work here
    }
}

这是非常简单的多线程解决方案,它可以满足我的需求。现在我想修复/改进它,因为我猜我做错了(程序永远不会结束,使用的内存比它应该的多。)。

  1. 我应该同时减少内存中存在的Runnable个对象的数量吗?如果我应该 - 我怎么能这样做?

  2. 我怎样才能检测到所有工作都已完成并退出程序(和线程)?

2 个答案:

答案 0 :(得分:0)

如果要减少运行的线程数,只需减小传递给固定线程池构造函数的大小。至于终止,在执行程序服务上调用shutdown和awaitTermination。但这只会减少活动线程的数量,而不会减少您在循环中创建的Runnable的数量。

答案 1 :(得分:0)

当你说program never ends, uses more memory than it should时,可能是由于很多原因,如

1)processFile()可能正在执行一些繁重的I / O操作(或)它被阻止某些I / O数据。

2)如果存在任何公共数据对象共享,则可能存在潜在的死锁

您的线程逻辑本身,非常直接ThreadPoolExecutor,我相信问题出在processFile()中的代码中。

由于您使用5初始化了池,ThreadPoolExecutor确保只有5个活动线程正在执行工作,而不管您要创建多少个可能的线程。

所以在这种情况下,我会更多地关注应用程序逻辑优化而不是线程管理。

如果您真的关心要创建多少Runnable个对象?然后,这是您的应用程序需求和可用资源之间的权衡。

如果每个线程任务都是独立的,并且所有这些线程都有执行时间限制,那么您可以在池中创建更多线程并添加更多资源。

当您在一个时间限制内定义一个包含5个线程的PoolExecutor并创建10,000个线程时,显然它们必须在内存中等待Future Task,直到线程可用。