我有一个多线程应用程序,可以动态创建数百个线程。当JVM的可用内存少于创建下一个Thread
所需的内存时,它无法创建更多线程。每个线程持续1-3分钟。有没有办法,如果我创建一个线程并且不启动它,可以使应用程序在有资源时自动启动它,否则等到现有线程死掉?
答案 0 :(得分:2)
如果您的运行接近极限,则在分配更多资源之前,您有责任检查可用内存。一种方法是使用MemoryUsage类,或使用以下之一:
Runtime.getRuntime().totalMemory()
Runtime.getRuntime().freeMemory()
...看看有多少内存可用。要弄清楚使用了多少,当然,您只需从total
中减去free
。然后,在您的应用中,只需设置一个MAX_MEMORY_USAGE
值,当您的应用使用该数量或更多内存时,它会停止创建更多线程,直到已用内存< / strong>已经回落到此阈值以下。这样,您始终以最大线程数运行,并且不会超出可用内存。
最后,不要尝试创建线程而不启动它们(因为一旦你创建了Thread
对象,你就已经占用了内存),只需执行以下操作之一:
答案 1 :(得分:2)
我最近遇到了类似的问题,我使用了本网站所描述的NotifyingBlockingThreadPoolExecutor
解决方案:
http://today.java.net/pub/a/today/2008/10/23/creating-a-notifying-blocking-thread-pool-executor.html
基本思想是这个NotifyingBlockingThreadPoolExecutor
将像ThreadPoolExecutor一样并行执行任务,但是如果你尝试添加任务并且没有可用的线程,它将等待。它允许我使用简单的“在我需要时创建我需要的所有任务”方法来保持代码,同时避免一次性实例化等待任务的巨大开销。
您的问题不清楚,但如果您使用的是直线而不是Executors和Runnables,那么您应该了解java.util.concurrent
包并使用它代替:http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html
答案 2 :(得分:1)
只需编写代码即可完全按照您的意愿执行操作。您的问题描述了解决方案的配方,只需实现该配方。此外,你应该认真考虑重新架构。你只需要一个线程来处理你想要做的事情并发,你就不能同时做好数百件事。
答案 3 :(得分:0)
这是一个替代的,较低级别的解决方案然后上面的mentioed NotifyingBlocking执行器 - 它可能不是那么理想,但实现起来很简单
如果你想要很多线程处于待机状态,那么你最终需要一种机制让他们知道什么时候可以“复活”。这听起来像信号量的情况。
确保每个线程在开始工作之前不分配不必要的内存。然后按如下方式实施:
1)在启动应用程序时创建n个线程,存储在队列中。您可以将此基于Runtime.getMemory(...)的结果,而不是对其进行硬编码。
2)同时,创建一个具有n-k许可证的信号量。再次,基于可用内存量。
3)现在,让每个n-k个线程定期检查信号量是否有许可,例如在两次检查之间调用Thread.sleep(...)。
4)如果一个线程注意到许可证,则更新信号量,并获得许可证。
如果满足您的需求,您可以稍后使用更复杂的轮询或等待/锁定机制来管理您的线程。