繁体   English   中英

Java-重用线程池

[英]Java - Reusing Thread Pool

对于我的Java项目,我想并行执行两个任务并将其结果合并。 问题是我必须在一种方法中执行此操作,该方法每次执行都会被调用多次(可能是1000次或更多)。 我尝试使用ExecutorService及其线程池,但是如果我将ExecutorService声明为类字段并开始向其提交工作,则有时会抛出

java.lang.OutOfMemoryError: unable to create new native thread

因此,我决定使用以下代码:

ExecutorService executor = Executors.newFixedThreadPool(2); 

Future<Integer> taskOne = executor.submit(new Callable<Integer> () {
    public Integer call() throws Exception {
        //Do work...
        return 0;
    }
});

Future<Integer> task2 = executor.submit(new Callable<Integer> () {
    public Integer call() throws Exception {
        //Do work...
        return 0;
    }
});

task1.get();
task2.get();

executor.shutdown();

while(!executor.isTerminated());

问题在于,使用这种新方法,与单线程解决方案相比,应用程序性能甚至更差。 我认为这是由于在每个方法调用上创建新线程池的开销。

因此,我的问题是:是否有一种方法可以执行相同的任务,而不必创建和关闭每个方法调用的线程池?

谢谢。

我并不一定要说它的劣质设计,而是要考虑的几件事。 就个人而言,我喜欢线程池,并且如果使用正确,它是一个可靠的解决方案。

性能下降的原因是,固定池大小为2时,一次只能运行两个线程。 可能您需要更大的数字-可能是10,可能是100-但至少您可以对其进行构图,以免耗尽内存。

就是说,如果由于创建了太多线程而导致原始设计用完了内存,那么您肯定需要限制一次活动线程的数量,因此您的性能将受到一定的打击……它只是不需要要么全部要么一无所有。

您还可以使用无限执行程序线程池,假设正在运行的线程会及时返回,以使您仍然不会使线程最大化。 如果线程以某种确定性的方式返回,则当线程返回到池中时,它可以立即用于下一个可用任务,而无需创建任何东西。 所以这很好。

综上所述,查看异常消息,也有可能在操作系统级别上无法创建更多线程,无论您在Java中所做的工作如何。 我有一个在CentOS上运行的服务,并且我合理地不得不增加每个进程的允许线程数(在这种情况下,一个Java进程在运行我的服务),因为有一个最大值,而且我正在尝试。 如果您正在运行某种linux风格,也可能是这样,尤其是因为看起来线程本身除了返回外什么都不做。

您描述的类字段解决方案听起来像是一个更好的设计。 该游泳池的大小是多少? 您应该调试OutOfMemoryError而不是切换到劣等设计。

暂无
暂无

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

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