Java 如何使用ExecutorService修复程序?

Java 如何使用ExecutorService修复程序?,java,executorservice,Java,Executorservice,所以,我是Java新手 我写了一个相对简单的程序,可以处理很多文件 它很慢,我想运行多个线程。在StackOverflow社区的帮助下,我制作了如下内容: public class FileProcessor { public static void main(String[] args) { // run 5 threads ExecutorService executor = Executors.newFixedThreadPool(5);

所以,我是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
    }
}
公共类文件处理器{
公共静态void main(字符串[]args)
{
//运行5个线程
ExecutorService executor=Executors.newFixedThreadPool(5);
int i;
//获取要处理的第一个和最后一个文件ID
int start=Integer.parseInt(args[0]);
int end=Integer.parseInt(args[1]);
for(i=start;i
这是一个非常简单的多线程解决方案,它满足了我的需求。现在我想修复/改进它,因为我想我做错了(程序永远不会结束,占用的内存比它应该使用的更多等等)

  • 我应该同时减少内存中存在的
    可运行的
    对象的数量吗?如果我应该-我怎么做

  • 如何检测所有作业是否已完成并退出程序(和线程)


  • 如果要减少运行的线程数量,只需减少传递给固定线程池构造函数的大小。至于终止,请在executor服务上调用shutdown并等待终止。但这只会减少活动线程的数量,而不会减少循环中正在创建的可运行程序的数量。

    当您说程序永不结束,使用的内存超过了它应该使用的内存时,
    ,这可能是由于许多原因,例如

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

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

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

    由于已使用5初始化池,因此无论要创建多少个可能的线程,
    ThreadPoolExecutor
    都会确保只有5个活动线程在执行该工作

    因此,在本例中,我将更多地关注应用程序逻辑优化,而不是线程管理

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

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


    当您定义一个
    PoolExecutor
    时,在一个时间限制内有5个线程,并创建10000个线程,那么很明显,它们必须作为
    未来任务
    在内存中等待,直到有一个线程可用

    等等,等等。。。我认为我的
    for
    循环在程序启动和后台处理“工作”时创建1000000个可运行对象。。。所以<代码>executor.submit(可运行)
    等待出现一些“空闲线程”?是。您创建了一个固定线程池,在本例中为5。您可以提交一百万个Runnable,但一次只能提交5个Runnable。当一个线程结束时,一个线程变为空闲线程,下一个可运行线程开始。。。我知道
    Runnable
    是在应该的时候启动的,同时启动的Runnable是有限的。但我担心的是执行1000000次迭代的
    循环的
    ,所以内存中大约有1000000个未启动可运行对象。搜索有关如何实现阻塞类型执行器的文章,以便在线程可用之前不会创建可运行对象,如果您担心内存中的所有对象都在等待空闲线程,那么我不确定它是否使用了太多RAM。我的processFile()方法非常简单。我只是对有1000000次迭代的大循环和该循环中的
    newrunnable()
    感到困惑。所以我的线程代码没有问题吗?线程逻辑看起来不错。但是,如果您确实想提高性能,那么请定义一个实现
    Runnable
    接口的类,并在其中包含
    processFile()
    逻辑。并使用该新类的实例启动执行器。