第68條:executor和task優先于線程

在java1.5,java平臺中增加了java.util.concurrent,這個包中包含了一個Executor Framework,這是一個很靈活的基于接口的任務執行工具它創建了一個在各方面都很好的隊列,只需要一行這樣的代碼:
ExecutorService executor = Executors.newSingleThreadExecutor();
下面是為執行提交一runnable的方法:
executor.execute(runnable);
下面是如何優雅的終止:
executor .shutdown();

如果想讓不止一個線程來處理來自這個隊列的請求,只要調用一個不同的靜態工廠,這個工廠創建了一種不同的executor service,稱作線程池。你可以用固定或者可變的數目的線程來創建一個線程池。
為特殊的應用程序選擇executor service是很有技巧的,如果是編寫小的程序,或者是輕栽的服務器,使用Executors.newCachedThreadPool通常是個不同的選擇,因為它不需要配置,并且一般情況下能夠正確的完成工作,但是對于大負載的服務器來說,緩存的線程池就不是很好的選擇了,在緩存的線程池中,被提交的任務沒有排成隊列,而是直接交給線程執行,如果沒有線程可以用,就創建一個新的線程。如果服務器負載的太重,以至于它的所有CPU都完全被占用了,當有更多的任務時,當有更多的任務時,就會創建更多的線程,這樣只會使情況變的更糟,因此在大負載的產品服務中,最好使用Executors.newFixedThreadPool,它為你提供一個包含固定線程數目的線程池.要想最大限度的控制它,就直接使用ThreadPoolExecutor類。

你不僅應該盡量不要編寫自己的工作隊列,即用上面的創建隊列的方式。而且還應該盡量不直接使用線程。現在關鍵的抽象不是Thread了,他之前既充當工作單元又是執行機制(run()方法,start()方法),現在工作單元和執行機制是分開的。現在關鍵的抽象是工作單元,稱作任務(task).任務有兩種:Runnable及其近親Callable(有返回值)。執行任務的通用機制是ExecutorService 。如果你從任務的角度看問題,并讓一個ExecutorService 替你執行任務,在選擇適當的執行策略方面就獲得了極大的靈活性。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容