2014-03-30 117 views
0

我初始化了一個帶有N個線程的exectuor服務。 N線程完成後,我想等待一段時間,然後重新使用N線程的新實例的執行程序。我該怎麼做呢?等待執行程序服務中的線程完成

這裏是我使用的是失敗的示例代碼:

 int NumberOfThreads=Integer.parseInt(PropertyHandler.getProperty("numberOfThreads")); 

     ExecutorService executor = Executors.newFixedThreadPool(NumberOfThreads); 
     log.info("Executor class has been initialized"); 
     while (true) { 

     jobStack = MrMestri.buildJobs(); 
     log.info("Creating a job stack of the search urls"); 
     if (jobStack.isEmpty()) 
     { 
      Thread.sleep(10000); 
     } 
     else { 
      int jobToken = 0; 
      while (jobStack.size() > 0) { 
      jobToken++; 
      MrRunnable worker = new MrRunnable(jobStack.pop()); 
      executor.execute(worker); 
      if (jobToken% Integer.parseInt(PropertyHandler.getProperty("totalTrends")) == 0)  { 
      log.info("All jobs for the clock cycle complete , waiting for next clock cycle to start. Number of jobs completed " + jobToken); 
      executor.shutdown(); 
      Thread.sleep(milliseconds); 

} 

現在,我使用執行關機,沒有遺囑執行人執行我的線程。我的線程實現可運行。

任何快速回復將有很大的幫助。謝謝。

+0

也許executor.awaitTermination?當你使用executor.shutdown()時,使用 –

+0

等待終止。或至少看起來像什麼時候或什麼時候超時。我不知道什麼時候可以在那裏設置,因爲我的一些迴應可能需要時間。所以我不認爲我想要走這條路。 –

回答

1

問題是與以下行置於內循環while

jobStack = MrMestri.buildJobs(); 

在這種情況下,下面的條件,如果你想處理下一N個任務

jobStack.isEmpty() 

移動這一條件在內while環和break內循環,如果條件滿足將始終返回false,因爲jobStack是從來沒有空處理接下來的N個任務。


示例代碼:

import java.util.Stack; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Executor { 

    /** 
    * @param args 
    * @throws InterruptedException 
    */ 
    public static void main(String[] args) throws InterruptedException { 
     int NumberOfThreads = Integer.parseInt("10"); 

     ExecutorService executor = Executors.newFixedThreadPool(NumberOfThreads); 
     while (true) { 

      Stack<Job> jobStack = MrMestri.buildJobs(); 
      int jobToken = 0; 
      while (true) { 
       if (jobStack.size() > 0) { 
        jobToken++; 
        MrRunnable worker = new MrRunnable(jobStack.pop()); 
        executor.execute(worker); 
        if (jobToken % Integer.parseInt("4") == 0) { 
         // executor.shutdown(); 
         System.out.println("short waiting..."); 
         Thread.sleep(2000); 

        } 
       } else { 
        System.out.println("long waiting..."); 
        Thread.sleep(10000); 
        break; 
       } 
      } 
     } 
    } 
} 

class MrMestri { 

    public static Stack<Job> buildJobs() { 
     Stack<Job> stack = new Stack<Job>(); 
     stack.push(new Job("A")); 
     stack.push(new Job("B")); 
     stack.push(new Job("C")); 
     stack.push(new Job("D")); 
     stack.push(new Job("E")); 
     stack.push(new Job("F")); 
     return stack; 
    } 

} 

class MrRunnable implements Runnable { 
    private Job job; 

    public MrRunnable(Job j) { 
     job = j; 
    } 

    @Override 
    public void run() { 
     System.out.println(job.getName()); 
    } 
} 

class Job { 
    private String name; 

    public Job(String n) { 
     name = n; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 
+0

謝謝,我認爲循環的這種用法非常棒。我從來沒有這樣想過。不得不退後一步看看我的代碼!好棒! –

+1

這解決了原始代碼中的問題,但不是等待線程完成的正確方法。無論出現什麼問題,總是比調用Thread.sleep更好。請參閱下面的invokeAll答案。 –

+0

但我需要它睡覺嗎? invokeall會讓我知道所有的線程是否完成,但之後我仍然需要使用線程休眠。那麼上面給出的方法仍然不正確? –

3

只是不關閉你的執行者 - 重新使用它。 生成的可調用任務,而不是Runnable接口和使用的集合:

executor.invokeAll 

它將執行所有任務,並儘快所有的人都做了迴歸。 如果MrRunnable是不是你的類或不管什麼原因,它必須實現Runnable你可以簡單地將其轉換爲可調用,如:

new Callable<Void>() 
    { 
     @Override 
     public Void call() throws Exception { 
      worker.run(); 
      return null; 
     } 
    };