2012-02-20 77 views
5

我做了以下错误:有没有办法让ExecutorService递归地工作?

  1. 调用Executors.newFixedThreadThreadPool做出池
  2. 设置Callable对象的列表,这样反过来call方法试图启动对非常相同的线程池任务
  3. 将它们放到队列与invokeAll

的结果对executo的队列死锁r服务。

我读过的Javadoc似乎没有禁止这组活动。我错过了什么?有什么方法来定制队列或服务,以便这可以工作?

+0

我也有类似的问题。假设我的线程池只有一个线程。我的外部Callable获取线程并调用一个子任务Callable。然后等待子任务完成。但是,由于池中唯一的线程已经与外部任务相关联,因此永远不会将其分配给内部任务,从而导致死锁。这个评估是否正确,或者我错过了什么? – 2013-10-11 15:09:05

+0

考虑到这一点之后,如果分支数量(即产生子任务的任务数量)大于池中线程的数量,似乎可能陷入死锁。所以,当你的分支计数超过线程数时,你可以连续执行子任务,而不是提交它们以便并行执行。我没有尝试过,但从概念上来说,它似乎应该起作用。 – 2013-10-11 18:51:09

回答

3

我对你的问题的理解就像下面的测试案例,它按照记录(如你所说)工作,并且我很乐意用于生产。你的例子与这个有什么不同?

import java.util.Date; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

class Scratch { 
    public static void main(String[] args) throws InterruptedException { 
     final ExecutorService pool = Executors.newFixedThreadPool(1); 
     pool.submit(new Callable<Void>() { 
      @Override 
      public Void call() throws Exception { 
       pool.submit(new Callable<Void>() { 
        @Override 
        public Void call() throws Exception { 
         System.out.println(new Date() + ": Second callable being run."); 
         pool.shutdown(); 
         return null; 
        } 
       }); 

       System.out.println(new Date() + ": First callable going to sleep..."); 
       Thread.sleep(2000); 
       System.out.println(new Date() + ": First callable finished!"); 
       return null; 
      } 
     }); 

     pool.awaitTermination(2, TimeUnit.MINUTES); 
    } 
} 

版画一样的东西:

Mon Feb 20 01:18:00 GMT 2012: First callable going to sleep... 
Mon Feb 20 01:18:02 GMT 2012: First callable finished! 
Mon Feb 20 01:18:02 GMT 2012: Second callable being run. 
+0

我的外层功能是使用pool.invokeAll,而不是pool.submit,所以它正在等待。我现在怀疑问题是所有的线程都用在'外部'线程上,所以没有任何工作可以完成。换句话说,我是一个白痴。 – bmargulies 2012-02-20 01:59:41

+0

尽管如此,一个正在执行的Callable应该仍然能够'submit()'一个新的Callable(因为'submit()'永远不会阻塞'newFixedThreadPool()')?除非你在Callables中也使用'pool.invokeAll()'? – FauxFaux 2012-02-20 02:05:16

+0

这是在lucene里面,我不知道。但是,如果所有的线程都在外面用完了,那么内部可以提交,但从来没有进展,然后外面的任何一个都不会完成。 – bmargulies 2012-02-20 02:30:06

相关问题