程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java ExecutorService生命周期

Java ExecutorService生命周期

編輯:關於JAVA

ExecutorService接口繼承了Executor接口,定義了一些生命周期的方法

public interface 

ExecutorService extends Executor {    
void shutdown();    
List<Runnable> shutdownNow();    
boolean isShutdown();    
boolean isTerminated();    
boolean awaitTermination(long timeout, TimeUnit unit)    
        throws InterruptedException;    
}

本文,我們逐一分析裡面的每個方法。

首先,我們需要創建一個任務代碼,這段任務代碼 主要是隨機生成含有10個字符的字符串

/** 
 * 隨機生成10個字符的字符串 
 * @author dream-victor 
 * 
 */
public class Task1 implements Callable<String> {  
      
    @Override
    public String call() throws Exception {  
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";  
        Random random = new Random();  
        StringBuffer sb = new StringBuffer();  
        for (int i = 0; i < 10; i++) {  
            int number = random.nextInt(base.length());  
            sb.append(base.charAt(number));  
        }  
        return sb.toString();  
    }  
      
}

然後,我們還需要一個長任務,這裡我們默認是沉睡10秒

/** 
 * 長時間任務 
 *  
 * @author dream-victor 
 *  
 */
public class LongTask implements Callable<String> {  
      
    @Override
    public String call() throws Exception {  
        TimeUnit.SECONDS.sleep(10);  
        return "success";  
    }  
      
}

OK,所有前期准備完畢,下面我們就來分析一下ExecutorService接口中和生命周期有關的這些方 法:

1、shutdown方法:這個方法會平滑地關閉ExecutorService,當我們調用這個方法時, ExecutorService停止接受任何新的任務且等待已經提交的任務執行完成(已經提交的任務會分兩類:一類是已 經在執行的,另一類是還沒有開始執行的),當所有已經提交的任務執行完畢後將會關閉ExecutorService。這 裡我們先不舉例在下面舉例。

2、awaitTermination方法:這個方法有兩個參數,一個是timeout即超 時時間,另一個是unit即時間單位。這個方法會使線程等待timeout時長,當超過timeout時間後,會監測 ExecutorService是否已經關閉,若關閉則返回true,否則返回false。一般情況下會和shutdown方法組合使用 。例如:

ExecutorService service = Executors.newFixedThreadPool(4);  
service.submit(new Task1());  
service.submit(new Task1());  
service.submit(new LongTask());  
service.submit(new Task1());  
      
service.shutdown();  
      
while (!service.awaitTermination(1, TimeUnit.SECONDS)) {  
    System.out.println("線程池沒有關閉");  
}  
System.out.println("線程池已經關閉");

這段代碼中,我們在第三次提交了一個長任務,這個任務 將執行10秒沉睡,緊跟著執行了一次shutdown()方法,假設:這時ExecutorService被立即關閉,下面調用 service.awaitTermination(1, TimeUnit.SECONDS)方法時應該返回true,程序執行結果應該只會打印出:“ 線程池已經關閉”。但是,真實的運行結果如下:

線程池沒有關閉  
線程池沒有關閉  
線程池沒有關閉  
線程池沒有關閉  
線程池沒有關閉  
線程池沒有關閉  
線程池沒有關閉  
線程池沒有關閉  
線程池沒有關閉  
線程池已經關閉

這說明我們假設錯誤,service.awaitTermination(1, TimeUnit.SECONDS)每隔一秒 監測一次ExecutorService的關閉情況,而長任務正好需要執行10秒,因此會在前9秒監測時ExecutorService 為未關閉狀態,而在第10秒時已經關閉,因此第10秒時輸出:線程池已經關閉。這也驗證了shutdown方法關閉 ExecutorService的條件。

3、shutdownNow方法:這個方法會強制關閉ExecutorService,它將取消所 有運行中的任務和在工作隊列中等待的任務,這個方法返回一個List列表,列表中返回的是等待在工作隊列中 的任務。例如:

ExecutorService service = Executors.newFixedThreadPool(3);  
service.submit(new LongTask());  
service.submit(new LongTask());  
service.submit(new LongTask());  
service.submit(new LongTask());  
service.submit(new LongTask());  
      
List<Runnable> runnables = service.shutdownNow();  
System.out.println(runnables.size());  
      
while (!service.awaitTermination(1, TimeUnit.MILLISECONDS)) {  
    System.out.println("線程池沒有關閉");  
}  
System.out.println("線程池已經關閉");

這段代碼中,我們限制了線程池的長度是3,提交了5個任 務,這樣將有兩個任務在工作隊列中等待,當我們執行shutdownNow方法時,ExecutorService被立刻關閉,所 以在service.awaitTermination(1, TimeUnit.MILLISECONDS)方法校驗時返回的是false,因此沒有輸出:線 程池沒有關閉。而在調用shutdownNow方法時,我們接受到了一個List,這裡包含的是在工作隊列中等待執行 的任務,由於線程池長度為3,且執行的都是長任務,所以當提交了三個任務後線程池已經滿了,剩下的兩次 提交只能在工作隊列中等待,因此我們看到runnables的大小為2,結果如下:

2
線程池已經關閉

4、isTerminated方法:這個方法會校驗ExecutorService當前的狀態是否為 “TERMINATED”即關閉狀態,當為“TERMINATED”時返回true否則返回false。例如:

      ExecutorService service = 

Executors.newFixedThreadPool(3);  
        service.submit(new Task1());  
        service.submit(new Task1());  
        service.submit(new LongTask());  
      
        service.shutdown();  
        System.out.println(System.currentTimeMillis());  
        while (!service.isTerminated()) {  
        }  
        System.out.println(System.currentTimeMillis

());
1303298818621
1303298828634
相差:10013毫秒,轉換一下除以1000,得到相差大約10秒

這10秒正 好是長任務執行的時間,因此在 ExecutorService正常關閉後isTerminated方法返回true。

5、 isShutdown方法:這個方法在ExecutorService關閉後返回true,否則返回false。方法比較簡單不再舉例。

以上討論是基於ThreadPoolExecutor的實現,不同的實現會有所不同需注意。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved