【问题标题】:Java ExecutorService heap space problemsJava ExecutorService 堆空间问题
【发布时间】:2012-04-08 05:16:07
【问题描述】:

我有一个 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中,所以过一段时间就大输入一个get

Exception in thread "pool-1-thread-2" java.lang.OutOfMemoryError: Java heap space

这是造成的,我认为是因为我添加到要执行的ExecutorSirvice 中的ThreadWorkers 数量巨大,因此内存不足。每个ThreadWorker 需要大约 40 Mb 的 RAM 才能满足所有需要。

有没有一种方法可以获取ExecutorService 中添加了多少线程(实现可运行接口的类的实例)?所以我可以在上面显示的代码中添加它(int the " // some code to prevent my problem"),如

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

所以我不会深入或广泛地使用递归并防止那些抛出异常的情况。

此致,小谢尔盖·阿加尼佐夫

【问题讨论】:

    标签: java multithreading exception executorservice


    【解决方案1】:

    如何使用ThreadPoolExecutor.CallerRunsPolicy 创建由BlockingQueue 支持的ThreadPoolExecutor

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

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

    【讨论】:

    • 创建TreadPoolExecutor es = new ThreadPoolExecutor(4, 4, 10000, TimUnit.MILLISECONDS, new ArrayBlockingQueue&lt;Runnable&gt;(10));,然后将rejectedHandler设置为es.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());。在此之后,如果我理解正确,它将处理我的问题,因为一旦运行线程数达到 4 并且排队线程数达到 10,下一个添加的任务将被拒绝并在主线程中执行,停止所有其他活动它。
    【解决方案2】:

    我认为您的案例非常适合 Java JDK 的“fork-join”框架。 (谷歌搜索该关键字。)

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

    不过,您必须将您的代码重新表述为该理念。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      • 2021-09-09
      • 2022-01-12
      • 1970-01-01
      • 2020-10-07
      相关资源
      最近更新 更多