gpt4 book ai didi

Java - 重用线程池

转载 作者:行者123 更新时间:2023-12-01 10:16:37 25 4
gpt4 key购买 nike

对于我的 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 - 但至少您可以对其进行设计,以免内存不足。

也就是说,如果原始设计由于创建了太多线程而导致内存不足,那么您肯定需要限制同时 Activity 的线程数量,因此您的性能将会受到一些影响...事实并非如此。不需要全有或全无。

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

总而言之,查看异常消息,也有可能在操作系统级别您无法创建更多线程,无论您在 Java 中做了什么。我有一个在 CentOS 上运行的服务,我必须合法地增加每个进程允许的线程数(在本例中,一个 Java 进程运行我的服务),因为有一个最大值,而我正在达到这个最大值。如果您正在运行某种 Linux 风格,也可能是这样,特别是因为看起来线程本身除了返回之外什么也不做。

关于Java - 重用线程池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35856139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com