2012-10-24 58 views
0

我希望有3個線程同時執行任務,並且還希望線程在一段時間內執行計劃任務(每10秒運行一次)。但是我希望當3個線程完成時只運行一次計劃任務,然後我希望此線程終止。 實現這些線程的最佳方式是什麼? ExecutorService接口適用於此。在其他線程完成後調度週期性任務

回答

3

這裏說我剛剛寫了一個例子:

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledFuture; 
import java.util.concurrent.TimeUnit; 

public class Example { 

    public static void main(String[] args) throws InterruptedException { 
     ScheduledFuture future = Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new MyScheduledTask(), 0, 10, TimeUnit.SECONDS); 
     ExecutorService executor = Executors.newFixedThreadPool(3); // pool composed of 3 threads 
     for (int i = 0; i < 3; i++) { 
      // for the example assuming that the 3 threads execute the same task. 
      executor.execute(new AnyTask()); 
     } 
     // This will make the executor accept no new threads 
     // and finish all existing threads in the queue 
     executor.shutdown(); 
     // expect current thread to wait for the ending of the 3 threads 
     executor.awaitTermination(Long.MAX_VALUE, TimeUnit.TimeUnit.NANOSECONDS); 
     future.cancel(false); // to exit properly the scheduled task 
     // reprocessing the scheduled task only one time as expected 
     new Thread(new ScheduledTask()).start(); 

    } 


} 

class MyScheduledTask implements Runnable { 
    @Override 
    public void run() { 
     //Process scheduled task here 
    } 
} 

class AnyTask implements Runnable { 
    @Override 
    public void run() { 
     //Process job of threads here 
    } 
} 
+0

它的工作原理。實際上,我的解決方案的問題是我把'sheduler.shutdown()'放在'executor.aWaitTermination()'的try塊內。我使用'ScheduledExecutorService'來創建調度程序。你對這個解決方案有什麼看法? – Manos

+0

@Manos Samatas嗯,你可以通過更新你的帖子來顯示你的代碼? – Mik378

+0

@Manos Samatas無論如何,'executor.aWaitTermination()'必須邏輯地放在'sheduler.shutdown()'之後,否則當前線程會等待最長時間,然後池會關閉......想象一下,性能。而且,沒有任何東西會阻止當前線程在等待其他作業終止3個線程之前繼續其任務。 – Mik378

1

這是一個週期性的任務計劃的其中一個例子執行任務一個接一個。任務調度程序接收一組任務,並在指定的時間間隔後,在單獨的線程中終止每個任務。 20秒後,主線程關閉調度程序並停止所有等待任務。

import java.util.Arrays; 
import java.util.Iterator; 
import java.util.List; 
import java.util.concurrent.CancellationException; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.ScheduledFuture; 
import java.util.concurrent.TimeUnit; 

public class Example { 

    class ScheduledRepeatingTask implements Runnable { 
     final ScheduledExecutorService scheduler = Executors 
       .newScheduledThreadPool(1); 

     List<Runnable> taskCollection; 
     Iterator<Runnable> taskIterator; 

     Runnable getCancelRunnable(final ScheduledFuture<?> future) { 

      Runnable cancelFuture = new Runnable() { 
       public void run() { 
        future.cancel(true); 
       } 
      }; 
      return cancelFuture; 
     } 

     public ScheduledRepeatingTask(Runnable[] tasks) { 
      super(); 
      taskCollection = Arrays.asList(tasks); 
      taskIterator = taskCollection.iterator(); 
     } 

     public void shutdownScheduler() throws InterruptedException { 
      scheduler.shutdown(); 
      boolean execTerminated = scheduler.awaitTermination(5, 
        TimeUnit.SECONDS); 

      if (!execTerminated) { 
       scheduler.shutdownNow(); 
      } 
     } 

     public boolean isShutdown(){    
      return scheduler.isShutdown(); 
     } 

     public void scheduleRepeatingTask(ScheduledFuture<?> future, 
       ScheduledFuture<?> futureCancel) { 

      try { 
       futureCancel.get(); 
       future.get(); 

      } catch (CancellationException e) { 
       System.out.println("cancelled."); 
      } catch (ExecutionException e) { 
       Throwable exp = e.getCause(); 
       if (exp instanceof RuntimeException) { 
        System.out.println("failed."); 
        RuntimeException rt = (RuntimeException) exp; 
        throw rt; 
       } 
      } catch (InterruptedException e) { 
       Thread.currentThread().interrupt(); 
      } finally { 
       if (!scheduler.isShutdown() && taskIterator.hasNext()) { 
        future = scheduler.scheduleAtFixedRate(taskIterator.next(), 
          2, 2, TimeUnit.SECONDS); 
        futureCancel = scheduler.schedule(
          getCancelRunnable(future), 5, TimeUnit.SECONDS); 
        scheduleRepeatingTask(future, futureCancel); 

       } 
      } 
     } 

     @Override 
     public void run() { 
      if (!scheduler.isShutdown() && taskIterator.hasNext()) { 
       ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(
         taskIterator.next(), 2, 2, TimeUnit.SECONDS); 
       ScheduledFuture<?> futureCancel = scheduler.schedule(
         getCancelRunnable(future), 5, TimeUnit.SECONDS); 
       scheduleRepeatingTask(future, futureCancel); 
      } 
     } 

    } 

    public static void main(String[] args) throws InterruptedException { 
     Example example = new Example(); 
     ExecutorService executor = Executors.newCachedThreadPool(); 

     Runnable[] tasks = { new Task1(), new Task2(), new Task1() }; 

     ScheduledRepeatingTask scheduledRepeatingTask = example.new ScheduledRepeatingTask(tasks); 

     executor.execute(scheduledRepeatingTask); 

     Thread.sleep(20000); 

     scheduledRepeatingTask.shutdownScheduler(); 

     executor.shutdown(); 

    } 

} 

class Task1 implements Runnable { 
    @Override 
    public void run() { 
     System.out.println("Task 1"); 
    } 
} 

class Task2 implements Runnable { 
    @Override 
    public void run() { 
     System.out.println("Task 2"); 
    } 
} 
相關問題