並發編程 10—— 任務取消 之 關閉 ExecutorService


  在之前的章節中,看到ExecutorService提供了兩種關閉方法:使用shutdown正常關閉,以及使用shutdownNow 強行關閉。在進行強行關閉時, shutdownNow 首先關閉當前正在執行的任務,然后返回所有尚未啟動的任務清單。

  這兩種關閉方式的差別在於各自的安全性和響應性:強行關閉的速度更快,但風險也更大,因為任務很可能在執行到一半時被結束;而正常關閉雖然速度慢,但卻更安全,因為 ExecutorService 會一直等到隊列中的所有任務都執行完成后才關閉。在其他擁有線程的服務中也應該考慮提供類似的關閉方式以供選擇。

  簡單的程序可以直接在main 函數中啟動和關閉全局的 ExecutorService。而在復雜程序中,通常會將 ExecutorService 封裝在某個更高級別的服務中,並且該服務能提供自己的生命周期方法,例如下面程序清單中,LogService的一種變化形式,它將管理線程的工作委托給一個 ExecutorService ,而不是由其自行管理。通過封裝 ExecutorService,可以將所有權鏈從應用程序擴展到服務以及線程,所有權鏈上的各個成員都將管理它所擁有的服務或線程的生命周期。

 

 1 /**
 2  * 7.16 封裝ExecutorService實現日志服務
 3  * @ClassName: LogService2
 4  * @author xingle
 5  * @date 2014-11-12 下午4:19:07
 6  */
 7 public class LogService2 {
 8     private final ExecutorService exec = Executors.newSingleThreadExecutor();
 9     private final PrintWriter writer;
10     
11     public LogService2(PrintWriter writer){
12         this.writer = writer;
13     }
14     
15     /**
16      * 產生日志
17      * @param msg 日志內容
18      * @throws InterruptedException
19      */
20     public void log(String msg){
21          exec.execute(new WriteTask(msg));
22     }
23 
24     /**
25      * 停止日志服務
26      * @throws InterruptedException 
27      */
28     public void stop(long timeout, TimeUnit unit) throws InterruptedException {
29         try {
30             exec.shutdown(); // 平緩關閉服務
31             // 關閉服務后, 阻塞到所有任務被執行完畢或者超時發生,或當前線程被中斷
32             exec.awaitTermination(timeout, unit);
33         } finally {
34             writer.close();
35         }
36     }
37 }
38 
39 class WriteTask implements Runnable
40 {
41     public WriteTask(String msg) {
42     }
43 
44     public void run()
45     {
46       //do something here
47     }
48 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM