java線程池分析

          SyndContentImpl.value=

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

             

           


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

           

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

           

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

           

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

           

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

           

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

           

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

           

           

           

          重要的Executors

           

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

           

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

           

           

           

          舉例說明:

           

          應用Executors來建立Thread pool

           

           

           

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

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

           

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

          newFixedThreadPool

          包括固定數(shù)量的Thread

          newSingleThreadExecutor

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

           

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

           

          • 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執(zhí)行過后的傳回結果。
          
          如果想利用Executors進行排程,例如排定某個工作30秒后執(zhí)行:

           

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

           

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

           

           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 脈凌網(wǎng)絡 閱讀(2258) 評論(0)  編輯  收藏

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


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 南充市| 保康县| 英山县| 高阳县| 长泰县| 旬邑县| 双牌县| 铁力市| 莱西市| 惠东县| 会同县| 碌曲县| 兰西县| 南汇区| 合作市| 湾仔区| 班戈县| 慈利县| 三门县| 蒲城县| 新乡县| 东乡| 峨眉山市| 金华市| 特克斯县| 会理县| 平顺县| 屯昌县| 体育| 正阳县| 桑日县| 娱乐| 慈溪市| 洪湖市| 开封市| 资阳市| 湖南省| 会泽县| 保靖县| 驻马店市| 钟祥市|