2012-04-08 69 views
2

我哈瓦一个Java mulithreading问题。我有以下的工人类:Java的ExecutorService的堆空间问题

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线程工作:ThreadWroker类的

public static int THREAD_NUMBER = 4; 
public static ExecutorServide es = Executors.newFixedThreadPool(THREAD_NUMBER); 

添加实例发生在这里:

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有多少线程(实现可运行接口的类的实例)?因此,我可以在上面的代码所示(INT的“//一些代码,以防止我的问题”),作为

while ("number of threads in the ExecutorService" > 10){ 
    Thread.sleep(10000); 
} 

,所以我不会去深或宽,我的递归和防止那些添加它异常投掷情况。

真诚,谢尔盖Aganezov JR。

回答

6

如何使用ThreadPoolExecutor.CallerRunsPolicy创建支持BlockingQueueThreadPoolExecutor

这样,当没有可用于运行任务的工作线程时,主线程(即添加新作业)将自行运行任务,从而防止添加更多作业。

关于ThreadPoolExecutor在其Javadoc页面的构造函数选项有更多详细信息。

+0

创建 'TreadPoolExecutor ES =新的ThreadPoolExecutor(4,4,10000,TimUnit.MILLISECONDS,新ArrayBlockingQueue (10));' 然后设置rejectedHandler到它 'es.setRejectedExecutionHandler(新的ThreadPoolExecutor .CallerRunsPolicy());'。 之后,如果我理解它是正确的,它会处理我的问题,因为一旦运行的线程数达到4,并且排队的线程数达到10,下一个添加的任务将被拒绝并执行主线程,停止所有其他线程活动。 – 2012-04-08 06:41:43

+0

是的,这是正确的。 – ulmangt 2012-04-08 14:56:56

1

我认为你的情况与Java JDK的“fork-join”框架非常匹配。 (Google针对该关键字)

Fork-Join通过尽可能延迟“拆分”来帮助您减少队列中的作业数量。

你必须虽然重新制定你的代码,这样的理念。