天天看點

JDK5.0新特性系列---11.2線程 任務執行架構

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

/**

    在J2SE之前啟動一個任務是通過調用Thread類的start方法來實作的,任務的送出和執行是同時進行的,如果想對任務的執行進行排程,或是控制同時執行的線程數量就需要額外的編寫代碼來完成.

    J2SE5.0提供了一個新的任務執行架構,可以輕松地高度和控制任務的執行,并且可以建立一個線程池來執行任務.

    執行個體介紹如何使用新的任務執行架構,運作Runnable和Callable任務,包括定時執行任務,按規律執行任務和停止任務.

關鍵技術剖析:

    使用新的任務執行架構的關鍵技術如下:

    1.Executor服務對象是用來執行Runnable任務的,常用的方法如下:

      execute方法用于執行Runnable類型的任務.

    2.ExecutorService服務對象能執行和終止Callable任務,它繼承了Executor,是以也能執行Runnable任務.常用的方法如下

      a) submit方法用來送出Callable或Runnable任務,并傳回代表此任務的Future對象.

      b) invokeAll方法批處理任務集合,并傳回一個代表這些任務的Future對象集合

      c) shutdown方法在完成自己已送出的任務後關閉服務,不再接受新任務.

      d) shutdownNow方法停止所有正在執行的任務并關閉服務.

      e) isTerminated測試是否所有任務都執行完畢了

      g) isShutdown測試是否該ExecutorService已被關閉

    3.ScheduledExecutorService服務對象繼承ExecutorService,提供了按時間安排執行任務的功能.常用的方法如下:

      a)schedule(task,initDelay)方法安排所送出的Callable或Runnable任務在initDelay指定的時間後執行.

      b)scheduleAtFixedRate方法安排所送出的Runnable任務按指定的間隔重複執行.

      c)scheduleWithFixedDelay方法安排所送出的Runnable任務在每次執行完後,等待delay所指定的時間後重複執行.

    4.Executors類用來建立各種服務對象,常用的方法如下:

      a)callable(Runnable task)方法将Runnable的任務轉化成Callable的任務.

      b)newSingleThreadExecutor方法産生一個ExecutorService對象,這個對象帶有一個線程池,線程池的大小會根據需要調整,線程執行完任務後傳回線程池,供執行下一次任務使用.

      c)newCachedThreadPool方法會産生一個ExecutorService對象,這個對象帶有一個線程池,線程池的大小會根據需要調整,線程執行完任務後傳回線程池,供執行下一次任務使用.

      d)newFixedThreadPool(int poolSize)方法産生一個ExecutorService對象,這個對象帶有一個大小為poolSize的線程池,若任務數量大于poolSize,任務會被放在一個隊列裡順序執行.

      e)newSingleThreadScheduledExecutor方法産生一個ScheduledExecutorService對象,這個對象的線程池大小為1,若任務多于一個,任務将按先後順序執行.

      f)newScheduledThreadPool(int poolSize)方法産生一個ScheduledExecutorService對象,這個對象的線程池大小為poolSize,若任務數量大于poolSize,任務會在一個隊列裡等待執行.

*/

public class ExecuteArch {

       /**該線程輸出一行字元串*/

       public static class MyThread implements Runnable{

              public void run(){

                     System.out.println("Task repeating. " + System.currentTimeMillis());

                     try{

                            Thread.sleep(1000);

                     }catch(InterruptedException e){

                            System.out.println("Task interrupted. " + System.currentTimeMillis());

                     }

              }

       }

       /**該Callable結束另一個任務*/

       public static class MyCallable implements Callable{

              private Future future;

              public MyCallable(Future future){

                     this.future = future;

              public String call(){

                     System.out.println("To cancell Task..." + System.currentTimeMillis());

                     this.future.cancel(true);

                     return "Task cancelled!";

       public static void main(String... args)throwsInterruptedException,ExecutionException{

              //産生一個ExcutorService對象,這個對象帶有一個線程池,線程池的大小會根據需要調整

              //線程執行完任務後傳回線程池,供執行下一次任務使用

              ExecutorService cachedService = Executors.newCachedThreadPool();

              Future myThreadFuture = cachedService.submit(new MyThread());

              Future myCallableFuture = cachedService.submit(newMyCallable(myThreadFuture));

              System.out.println(myCallableFuture.get());

              System.out.println("--------------------");

              //将Runnable任務轉換成 Callable任務

              Callable myThreadCallable = Executors.callable(new MyThread());

              Future myThreadCallableFuture = cachedService.submit(myThreadCallable);

              //對于Runnable任務,轉換成Callable任務後,也沒有傳回值

              System.out.println(myThreadCallableFuture.get());

              cachedService.shutdownNow();

              //産生一個ExecutorService對象,這個對象帶有一個大小為poolSize的線程池

              //若任務大于poolSize,任務會被放在一個queue裡順序執行

              ExecutorService fixedService = Executors.newFixedThreadPool(2);

              fixedService.submit(new MyThread());

              //由于線程池大小為2,是以後面的任務必須等待前面的任務執行完畢後才能被執行

              myThreadFuture = fixedService.submit(new MyThread());

              myThreadFuture = fixedService.submit(new MyCallable(myThreadFuture));

              fixedService.shutdown();

              //産生一個ScheduleExecutorService對象,這個對象的線程池大小為poolSize

              //若任務數量大于poolSize,任務會在一個queue裡等待執行

              ScheduledExecutorService fixedScheduledService = Executors.newScheduledThreadPool(2);

              MyThread task1 = new MyThread();

              //使用任務執行服務立即執行任務1,而且此後每隔2秒執行一次任務1

              myThreadFuture = fixedScheduledService.scheduleAtFixedRate(task1, 0, 2, TimeUnit.SECONDS);

              MyCallable task2 = new MyCallable(myThreadFuture);

              //使用任務執行服務等待5秒後執行任務2,執行它後将任務1關閉.

              myCallableFuture = fixedScheduledService.schedule(task2,5,TimeUnit.SECONDS);

              fixedScheduledService.shutdownNow();            

}