2013-02-21 65 views
2

有一个循环轮询从GenericObjectPool中借用对象。池本身的大小为1.代码如下 -将对象返回到单独的线程池中

final CompletionService completionService = new ExecutorCompletionService(getExecutorServices());    
int counter = 0; 

    for (Iterator iter = AList.iterator(); iter.hasNext();) { 

       borrowed = this.getPool().borrowObject(); 

       if (borrowed == null) { 
        throw new Exception("not set"); 
       } else {   
        completionService.submit(borrowed,borrowed); 
        counter ++; 
       } 
    } 

由于池的大小为1,所以在第一次借入后,它会被耗尽并被阻塞。 要返回的对象回到游泳池,我想运行下面一个单独的线程 -

new Runnable() { 

    public void run() { 
     for (int i = 0; i < counter; i++) { 

      borrowed = completionService.take().get(); 
      status = borrowed.getStatus(); 

      getPool().returnObject(borrowed); 
         counter --; 

      if (status = 1) { 
       getExecutorServices().shutdownNow(); 
       return; 
      } 
     } 
    } 

}; 

这是一个阻塞调用CompletionService作用于每个线程完成并释放它使其可用于借。

但是这种设计有一些缺点,例如不能从Runnable中读取父代的计数器。

回答

0

我创建了一个CallableDecorator来返回值形式Runnable来监视线程并修复它。

0

该计数器不是线程安全的。使用AtomicInteger并使其可用于可运行和第一个代码块。

+0

在第一个代码块中,借来的对象被重复提交。那应该没问题? – fortm 2013-02-21 13:08:58

+0

completionService.submit(借用,借用)来自另一个问题的另一个答案,我相信。您需要这样做是因为您提交了一个可运行的程序,并希望具有相同类型的可运行结果,因此您可以稍后重新提交。 CS通常用于执行返回结果的可调用对象,但您也可以将它用于可运行对象。就像在这个例子中。 – 2013-02-21 13:18:35

相关问题