java線程池分析

          SyndContentImpl.value=

              在Java 5.0之前啟動一個任務是通過調用Thread類的start()方法來實現的,任務的提于交和執行是同時進行的,如果你想對任務的執行進行調度或是控制 同時執行的線程數量就需要額外編寫代碼來完成。5.0里提供了一個新的任務執行架構使你可以輕松地調度和控制任務的執行,并且可以建立一個類似數據庫連接 池的線程池來執行任務。這個架構主要有三個接口和其相應的具體類組成。這三個接口是Executor, ExecutorService、ScheduledExecutorService,讓我們先用一個圖來顯示它們的關系:

             

           


          圖的左側是接口,圖的右側是這些接口的具體類。注意Executor是沒有直接具體實現的。

           

          Executor接口:是用來執行Runnable任務的,它只定義一個方法:

           

          • execute(Runnable command):執行Ruannable類型的任務

           

          ExecutorService接口:ExecutorService繼承了Executor的方法,并提供了執行Callable任務和中止任務執行的服務,其定義的方法主要有:

           

          • submit(task):可用來提交Callable或Runnable任務,并返回代表此任務的Future對象
          • invokeAll(collection of tasks):批處理任務集合,并返回一個代表這些任務的Future對象集合
          • shutdown():在完成已提交的任務后關閉服務,不再接受新任務
          • shutdownNow():停止所有正在執行的任務并關閉服務。
          • isTerminated():測試是否所有任務都執行完畢了。
          • isShutdown():測試是否該ExecutorService已被關閉

           

          ScheduledExecutorService接口在ExecutorService的基礎上,ScheduledExecutorService提供了按時間安排執行任務的功能,它提供的方法主要有:

           

          • schedule(task, initDelay): 安排所提交的Callable或Runnable任務在initDelay指定的時間后執行。
          • scheduleAtFixedRate():安排所提交的Runnable任務按指定的間隔重復執行
          • scheduleWithFixedDelay():安排所提交的Runnable任務在每次執行完后,等待delay所指定的時間后重復執行。

           

           

           

          重要的Executors

           

          雖然以上提到的接口有其實現的具體類,但為了方便Java 5.0建議使用Executors的工具類來得到Executor接口的具體對象,需要注意的是Executors是一個類,不是Executor的復數 形式。Executors提供了以下一些static的方法:

           

          • callable(Runnable task): 將Runnable的任務轉化成Callable的任務
          • newSingleThreadExecutor: 產生一個ExecutorService對象,這個對象只有一個線程可用來執行任務,若任務多于一個,任務將按先后順序執行。
          • newCachedThreadPool(): 產生一個ExecutorService對象,這個對象帶有一個線程池,線程池的大小會根據需要調整,線程執行完任務后返回線程池,供執行下一次任務使用。
          • newFixedThreadPool(int poolSize):產生一個ExecutorService對象,這個對象帶有一個大小為poolSize的線程池,若任務數量大于poolSize,任務會被放在一個queue里順序執行。
          • newSingleThreadScheduledExecutor:產生一個ScheduledExecutorService對象,這個對象的線程池大小為1,若任務多于一個,任務將按先后順序執行。
          • newScheduledThreadPool(int poolSize): 產生一個ScheduledExecutorService對象,這個對象的線程池大小為poolSize,若任務數量大于poolSize,任務會在一個queue里等待執行

           

           

           

          舉例說明:

           

          應用Executors來建立Thread pool

           

           

           

          有時候您需要建立一堆Thread來執行一些小任務,然而頻繁的建立Thread有時會是個開銷,因為Thread的建立必須與作業系統互動,如果能建立一個Thread pool來管理這些小的Thread并加以重復使用,對于系統效能會是個改善的方式。

          您可以使用Executors來建立Thread pool,Executors有幾個static方法,列出如下:

           

          方法 說明
          newCachedThreadPool 建立可以快取的Thread,每個Thread預設可idle 60秒

          newFixedThreadPool

          包括固定數量的Thread

          newSingleThreadExecutor

          只有一個Thread,循序的執行指定給它的每個任務
          newScheduledThreadPool 可排程的Thread
          newSingleThreadScheduledExecutor 單一可排程的Thread

           

          舉個簡單的實例,下面的程式使用newFixedThreadPool方法建立Thread pool,當中包括五個可以重復使用的Thread,您可以指定Runnable物件給它,程式中會產生十個Runnable物件,由于Thread pool中只有五個可用的Thread,所以后來建立的五個Runnable必須等待有空閑的Thread才會被執行:

           

          • ExecutorDemo.java

           

          package onlyfun.caterpillar;
          
          import java.util.concurrent.ExecutorService;
          import java.util.concurrent.Executors;
          
          public class ExecutorDemo {
           public static void main(String[] args) {
            ExecutorService service = Executors.newFixedThreadPool(5);
          
            for(int i = 0; i < 10; i++) {
             final int count = i;
             service.submit
          (new Runnable() {
              public void run() {
               System.out.println(count);
               try {
                Thread.sleep(2000);
               } catch (InterruptedException e) {
                e.printStackTrace();
               }
          
              }
             });
            }
          
            service.shutdown(); // 最后記得關閉Thread pool
          
           }
          }

           

          submit()方法也接受實作Callable介面的物件,最后傳回Future物件,可以取得Callable執行過后的傳回結果。
          
          如果想利用Executors進行排程,例如排定某個工作30秒后執行:

           

           ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor( );          scheduler.schedule(new Runnable( ) {                                 public void run() {                                     // 排程工作                                 }                             },                             30, TimeUnit.SECONDS);

           

          或排定某個工作5秒后執行,之后每30秒執行一次:

           

           ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor( );          final ScheduledFuture future = scheduler.scheduleAtFixedRate(new Runnable( ) {                                 public void run() {                                     // 排程工作                                     System.out.println("t");                                 }                             },                             0, 5, TimeUnit.SECONDS);                   // 排定 60 秒后取消future          scheduler.schedule(new Runnable( ) {              public void run( ) {                future.cancel(false);              }            }, 60, TimeUnit.SECONDS);如上所示,想要取消排程任務,可以呼叫ScheduledFuture的cancel()方法。

           



          posted on 2012-02-17 18:51 脈凌網絡 閱讀(2266) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 昭苏县| 固镇县| 深水埗区| 岱山县| 昌图县| 延庆县| 巢湖市| 株洲市| 曲靖市| 丰宁| 普兰店市| 汉沽区| 乐安县| 万安县| 饶平县| 广昌县| 龙泉市| 乌审旗| 扎兰屯市| 赤城县| 黔南| 华宁县| 汤阴县| 阳泉市| 文山县| 宁都县| 陇西县| 深圳市| 进贤县| 西和县| 恩施市| 保定市| 平乐县| 堆龙德庆县| 玉林市| 岑溪市| 迭部县| 积石山| 宜兰市| 浮山县| 平乡县|