如何管理超过32k的线程

qsp*_*qsp 7 java multithreading

由于迫切需要,我刚刚学习了多线程编程.请帮我解决这个问题.

我有一个字符串处理任务,可以很好地分为小子任务.

while (...){
    ...
    // assign task for handler
    Thread t = new Thread(new PCHandler(counter,pc));
    t.start();
    counter++;
}
Run Code Online (Sandbox Code Playgroud)

问题是我将需要大约500K线程来完成这项任务.我遇到了一个错误:

引起:java.lang.OutOfMemoryError:无法创建新的本机线程

我谷歌一段时间似乎JVM只允许我制作最大32K线程.有一些指令可以通过修改配置文件来扩展此限制.但我想避免修改用户的计算机.那么你能否给我一个如何在极限内明智地管理它们的建议?谢谢.

Gra*_*ray 23

问题是我将需要大约500K线程来完成这项任务.我遇到了[内存错误].

听起来你应该使用一个线程池,这样你就可以提交大量的工作,但只能在少量的线程中运行它们.

// create a thread pool with 10 threads, this can be optimized to your hardware
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// submit your handlers to the thread-pool
for (PCHandler handler : handlersToDo) {
    threadPool.submit(handler);
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
...
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,那么我想知道有关实际需要500k并发运行线程的系统的更多细节.您可以通过一些内存设置调整和增加盒子上的核心内存来实现这一点,但我怀疑重新设计应用程序是有序的.

正如@Peter在评论中提到的,为了优化池中的线程数,您可以获得可用处理器的数量和其他系统规格来解决这个问题.但这在很大程度上取决于你的PCHandler课程CPU密集程度.它做的IO越多,可以利用的并发性就越多.可能会使用传递给newFixedThreadPool(...)方法的不同值进行一些测试运行,以确定那里的最佳设置.

  • 除了上述内容之外,如果您考虑500k单独任务,您的任务可能太小.每项任务本身都应该耗费一些时间.例如,有500个工作分别执行1000个子任务,而不是500个工作,这可能是有意义的.管理线程的开销很大,每个人都应该做一大堆工作. (4认同)