繁体   English   中英

CachedThreadPool满足但不启动第二个线程的任何原因?

[英]Any reason why CachedThreadPool would be at full capacity but not initiate a second thread?

想象一下,需要时间的软件会收集大量文本文件(每个100多MB),处理它们并放入数据库。 我正在尝试通过使用更多内核来优化它(对于这台机器来说恰好是8个,具有超线程的四核i7)。

考虑以下代码:

    ExecutorService es = Executors.newCachedThreadPool(
            new ThreadFactory() {
                private final AtomicInteger threadNumber = new AtomicInteger(1);
                private final String namePrefix = "awesome-thread-";

                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement());
                    if (t.isDaemon()) 
                        t.setDaemon(false);
                    return t;
        }
    });

    while((e = upp.getNextEntry()) != null){

        // start time-consuming process in a separate thread to speed up
        Future<Set<Fragment>> fut = es.submit(new FragmentTask(e.getSomeProperty()));       

        /* do other stuff #sequentially# with entry e
         * it may or may not take as long as previous step
         * depending on e 
         */

        Set<Fragment> set = fut.get(); 
        for(Fragment frag : set){
            // do stuff with frag
        }                       
    }

这里的FragmentTask包含一个递归算法,根据e ,执行需要几到几千毫秒才能执行。

我最初将线程池实现为FixedThreadPool但是当我直观地检查线程的运行方式时(通过JVisualVM),我意识到线程通常是空闲的。 我想我会尝试使用CachedThreadPool作为替代方案,但看起来因为池是一个单独的线程,在整个while循环中几乎以100%运行。 在此过程中,不会随时创建池的辅助线程,其他核心也非常闲置。 真正有趣的是,执行while循环中其余部分的“主”工作线程实际上一直在“等待”。

我觉得这有点奇怪,因为我希望至少有两个线程应该能够以更高的效率运行,一个运行FragmentTask ,另一个运行while循环中的其余部分,最多到fut.get()

关于幕后可能发生什么的任何想法? 代码“太顺序”是否可以使用线程池?

你正在以错误的方式使用期货来并行执行。 您需要先提交所有任务并保存他们的未来,然后再打电话。 调用get等待任务完成。

你现在正在做的是提交一个在自己的线程上执行的任务,然后主线程等待任务完成。 冲洗并重复。

你说你期待两个线程。 这确实是你拥有的 - 主线程和一个执行程序线程。

问题不在于线程池实现。 您尝试一次获得一个Future ,因此您的程序基本上是单线程的。

你应该做的是创建你的CallableCollection并使用:

final List<Future<Set<Fragment>>> results
    = executor.invokeAll(yourCollectionOfCallables);

然后循环results 当一个任务完成时,线程池将尽力启动具有新任务的线程; 更重要的是,当您遍历所有列表时,保证所有任务都已完成(成功与否)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM