線程池ExecutorService的submit和execute

wangjianme 12年前發布 | 196K 次閱讀 Thread Executor 線程池 Java開發

線程池ExecutorServicesubmitexecute

Java5之后,并發線程這塊發生了根本的變化,最重要的莫過于新的啟動、調度、管理線程的一大堆API了。在Java5以后,通過 Executor來啟動線程比用Threadstart()更好。在新特征中,可以很容易控制線程的啟動、執行和關閉過程,還可以很容易使用線程池的特 性。

 

一、創建任務

 

任務就是一個實現了Runnable接口的類。

創建的時候實run方法即可。

 

二、執行任務

 

通過java.util.concurrent.ExecutorService接口對象來執行任務,該接口對象通過工具類java.util.concurrent.Executors的靜態方法來創建。

 

Executors此包中所定義的 ExecutorExecutorServiceScheduledExecutorServiceThreadFactory Callable 類的工廠和實用方法。

 

ExecutorService提供了管理終止的方法,以及可為跟蹤一個或多個異步任務執行狀況而生成 Future 的方法。 可以關閉 ExecutorService,這將導致其停止接受新任務。關閉后,執行程序將最后終止,這時沒有任務在執行,也沒有任務在等待執行,并且無法提交新任 務。

executorService.execute(new TestRunnable());

 

1、創建ExecutorService

通過工具類java.util.concurrent.Executors的靜態方法來創建。

Executors此包中所定義的 ExecutorExecutorServiceScheduledExecutorServiceThreadFactory Callable 類的工廠和實用方法。

 

比如,創建一個ExecutorService的實例,ExecutorService實際上是一個線程池的管理工具:

        ExecutorService executorService = Executors.newCachedThreadPool();

        ExecutorService executorService = Executors.newFixedThreadPool(3);

        ExecutorService executorService = Executors.newSingleThreadExecutor();

 

2、將任務添加到線程去執行

當將一個任務添加到線程池中的時候,線程池會為每個任務創建一個線程,該線程會在之后的某個時刻自動執行。

 

示例1

    @Test

    public void testDemo() throws Exception {

       //單例線程,任意時間(同一時間)池中只能有一個線程

       ExecutorService es = Executors.newSingleThreadExecutor();

       es.execute(new Runnable() {

           @Override

           public void run() {

              System.err.println("線程啟動并運行"+Thread.currentThread().getName());

           }

       });

       es.execute(new Runnable() {

           @Override

           public void run() {

              System.err.println("第二個也運行了"+Thread.currentThread().getName());

           }

       });

       //Thread.sleep(1000 * 60 * 60);

    }

運行結果如下:兩個都會執行,但程序只會使用一個線程來運行。

線程啟動并運行pool-1-thread-1

第二個也運行了pool-1-thread-1

 

示例2:

    @Test

    public void testDemo3() throws Exception {

       //聲明一個線程池

       ExecutorService ex = Executors.newCachedThreadPool();

       for (int i = 0; i < 4; i++) {

           final int a = i;

           //每一次execute方法,都是向池中放入一個對象

           ex.execute(new Runnable() {

              public void run() {

                  while(true){

                     System.err.println("測試...."+a+">"

                            +Thread.currentThread().getName()+","

                            +Thread.currentThread().isDaemon());

                     try{

                         Thread.sleep(2000);

                     }catch(Exception e){

                         e.printStackTrace();

                     }

                  }

              }

           });

       }

       Thread.sleep(1000*60*60);

    }
輸出的結果如下:從中可以發現,第四個一組輸出,即一共創建了四個線程,每次每個線程都會執行輸出,但不按順序:位每一次輸出都四個算是一組

測試....0>pool-1-thread-1,false

測試....3>pool-1-thread-4,false

測試....2>pool-1-thread-3,false

測試....1>pool-1-thread-2,false

測試....0>pool-1-thread-1,false

測試....3>pool-1-thread-4,false

測試....2>pool-1-thread-3,false

測試....1>pool-1-thread-2,false

測試....1>pool-1-thread-2,false

測試....2>pool-1-thread-3,false

測試....3>pool-1-thread-4,false

測試....0>pool-1-thread-1,false

 

示例3:

    public void testCall() throws Exception{

       //聲明一個類,可以被調用,類似于線程,但它可以擁有返回值

       class MyCall implements Callable<String>{

           private int seq;

           public MyCall(int seq){

              this.seq=seq;

           }

           //拋出異常并可以擁有返回值

           public String call() throws Exception {

              System.err.println("執行"+seq+","+Thread.currentThread().getName());

              Thread.sleep(3000);

              System.err.println("Weak up "+seq);

              return "完成"+seq;//這是返回值

           }

       }

       ExecutorService es = Executors.newCachedThreadPool();//創建線程池對象

       List<Future<String>> result =new ArrayList<Future<String>>();//放結果用的集合

       for(int i=0;i<3;i++){

           Future<String> f=es.submit(new MyCall(i));//線程執行完成以后可以通過引用獲取返回值

           result.add(f);

       }

       for(Future<String> f:result){

           System.err.println("返回值:"+f.get());//輸出返回的值

       }

       System.err.println("完成....");

    }

 

 本文由用戶 wangjianme 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!