2014-04-01 128 views
1

我提交了許多在多線程上運行的工人。如果有正在運行的員工返回虛假值,我們停止或不提交其他員工。以下是我的示例課程。我應該在TODO部分做什麼?請在這個問題上給我一些建議。每當工人返回虛假值時停止其他工人

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Date; 
import java.util.List; 
import java.util.concurrent.*; 

public class CompletionServiceTest 
{ 
    public static void main(final String[] args) 
    { 
     ExecutorService cs = Executors.newFixedThreadPool(1); 
     Collection<Worker> tasks = new ArrayList<Worker>(10); 

     for(int i=0;i<10;i++) { 
      tasks.add(new Worker(i+1)); 
     } 

     List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>(tasks.size()); 
     try 
     { 
      for (Callable task : tasks) 
      { 
       futures.add(cs.submit(task)); 
      } 

     // TODO 
     // Check if any false value is returned 
     // Then stop all running tasks, no need to run other tasks anymore 
     }   
     finally 
     { 
      //Cancel by interrupting any existing tasks currently running in Executor Service 
      for (Future<Boolean> f : futures) 
      { 
       f.cancel(true); 
      } 
     } 
     System.out.println(new Date()+":Done"); 
    } 
} 

class Worker implements Callable<Boolean> 
{ 
    private int number; 
    public Worker(int number) 
    { 
     this.number=number; 
    } 

    public Boolean call() 
     throws InterruptedException 
    { 
     try 
     {    
      Thread.sleep(50000); 
      if(number % 4 == 0) { 
       return false; 
      } else { 
       Thread.sleep(500000); 
      } 
     } 
     catch(InterruptedException ie) 
     { 
      System.out.println("Worker Interuppted"); 
      throw ie; 
     } 

     return true; 
    } 
} 
+2

你研究過例如在'ExecutorCompletionService'的javadoc中?這幾乎是你所需要的。 –

+0

我會試試這個。感謝您的幫助,marko :) :) – Barcelona

回答

0

我周圍玩想出了這個解決方案,如果你還在尋找一個工作示例:

class CompletionServiceTest { 

    public static void main(String... args) throws Exception { 
     ExecutorService es = newFixedThreadPool(10); 
     CompletionService<Boolean> cs = new ExecutorCompletionService<Boolean>(es); 
     for (int i = 1; i <= 10; i++) cs.submit(new Worker(i)); 
     int count = 0; 
     while (++count <= 10 && cs.take().get()); 
     es.shutdownNow(); 
    } 
} 

class Worker implements Callable<Boolean> { 

    private final int number; 

    public Worker(int number) { 
     this.number = number; 
    } 

    @Override public Boolean call() throws Exception { 
     try { 
      Thread.sleep(1000 + number * 100); 
      if (number % 4 == 0) { 
       System.out.printf("worker [%d] failed.\n", number); 
       return false; 
      } 
      System.out.printf("worker [%d] done!\n", number); 
      return true; 
     } catch (InterruptedException ie) { 
      System.out.printf("Worker [%d] stopped!\n", number); 
      throw ie; 
     } 
    } 
} 

輸出看起來是這樣的:

worker [1] done! 
worker [2] done! 
worker [3] done! 
worker [4] failed. 
Worker [9] stopped! 
Worker [7] stopped! 
Worker [8] stopped! 
Worker [5] stopped! 
Worker [6] stopped! 
Worker [10] stopped! 
+0

不認爲它會工作,因爲'future.get()'會等待第一個工人終止,但情況並非如此 – JohnnyAW

+0

OP可能不想立即關閉執行者服務。通常它是一個應用程序範圍的單例,並滿足併發執行的所有需求。這就是爲什麼顯式取消所有剩餘期貨的更詳細的變體是首選。 –