我有一个Java多线程问题。我有以下工人阶级:
public class ThreadWorker implements Runnable {
//some code in here
public void run(){
// invokes some recursion method in the ThreadWorker itself,
// which will stop eventually
{
}
使用线程我正在使用ExecutorService
:
public static int THREAD_NUMBER = 4;
public static ExecutorServide es = Executors.newFixedThreadPool(THREAD_NUMBER);
在此处添加ThreadWroker
类的实例:
public void recursiveMethod(Arraylist<Integers> elements, MyClass data){
if (elements.size() == 0 && data.qualifies()){
ThreadWorker tw = new ThreadWorker(data);
es.execute(tw);
return;
}
for (int i=0; i< elements.size(); i++){
// some code to prevent my problem
MyClass data1 = new MyClass(data);
MyClass data2 = new MyClass(data);
ArrayList<Integer> newElements = (ArrayList<Integer>)elements.clone();
data1.update(elements.get(i));
data2.update(-1 * elements.get(i));
newElements.remove(i);
recursiveMethod(newElements, data1);
recursiveMethod(newElements, data2);
{
}
问题在于递归树的深度非常大,因此它的宽度也很大,所以ThreadWorkers
中添加了很多ExecutorService
,因此在大输入之后的一段时间内得到
Exception in thread "pool-1-thread-2" java.lang.OutOfMemoryError: Java heap space
这是由于我认为由于ThreadWorkers
我要添加到ExecutorSirvice
的大量数据而导致的,所以内存不足。每个ThreadWorker
只需要大约40 Mb的RAM。
是否有一种方法可以获取ExecutorService
中添加了多少个线程(实现可运行接口的类的实例)?所以我可以在上面显示的代码中添加它(在“//一些代码以防止我的问题”中),如
while ("number of threads in the ExecutorService" > 10){
Thread.sleep(10000);
}
所以我不会深入或广泛地使用我的递归并防止那些抛出异常的情况。
此致,Sergey Aganezov jr。
答案 0 :(得分:6)
如何使用ThreadPoolExecutor创建由BlockingQueue
支持的ThreadPoolExecutor.CallerRunsPolicy。
这样,当没有可用于运行任务的工作线程时,主线程(添加新作业)会自行运行任务,从而阻止添加任何更多作业。
有关{JAVadoc页面上ThreadPoolExecutor的构造函数选项的详细信息。
答案 1 :(得分:1)
我认为您的案例非常适合Java JDK的“fork-join”框架。 (Google用于该关键字。)
Fork-Join可以通过尽可能地延迟“拆分”来帮助您减少队列中的作业数量。
你必须将你的代码改编成这种哲学。