經過java.util.concurrent.ExecutorService接口對象來執行任務,該接口對象經過工具類java.util.concurrent.Executors的靜態方法來建立。java
Executors此包中所定義的 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 類的工廠和實用方法。異步
ExecutorService提供了管理終止的方法,以及可爲跟蹤一個或多個異步任務執行情況而生成 Future 的方法。 能夠關閉 ExecutorService,這將致使其中止接受新任務。關閉後,執行程序將最後終止,這時沒有任務在執行,也沒有任務在等待執行,而且沒法提交新任 務。工具
executorService.execute(new TestRunnable());性能
一、建立ExecutorServicethis
經過工具類java.util.concurrent.Executors的靜態方法來建立。spa
Executors此包中所定義的 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 類的工廠和實用方法。線程
好比,建立一個ExecutorService的實例,ExecutorService其實是一個線程池的管理工具:設計
ExecutorService executorService = Executors.newCachedThreadPool();code
ExecutorService executorService = Executors.newFixedThreadPool(3);對象
ExecutorService executorService = Executors.newSingleThreadExecutor();
二、將任務添加到線程去執行
當將一個任務添加到線程池中的時候,線程池會爲每一個任務建立一個線程,該線程會在以後的某個時刻自動執行。
3、關閉執行服務對象
executorService.shutdown();
package javaBasic; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 建立由Callable對象組成的的執行線程池 * * @author markGao * */ public class ExecutorServiceSample { public static void main(String[] args) { int numberOfThreads = java.lang.Runtime.getRuntime() .availableProcessors(); ExecutorService pool = Executors.newFixedThreadPool(numberOfThreads); for (int i = 0; i < numberOfThreads; i++) { pool.execute(new TestRunnable()); System.out.println("************* execute Processors" + i + " *************"); } pool.shutdown(); } } /** * Runnable任務沒有返回值 * * @author markGao * */ class TestRunnable implements Runnable { public void run() { System.out.println(Thread.currentThread().getName() + "線程被調用了。"); while (true) { try { Thread.sleep(5000); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
5、獲取任務的執行的返回值
在Java5之 後,任務分兩類:一類是實現了Runnable接口的類,一類是實現了Callable接口的類。二者均可以被ExecutorService執行,可是 Runnable任務沒有返回值,而Callable任務有返回值。而且Callable的call()方法只能經過ExecutorService的 submit(Callable<T> task) 方法來執行,而且返回一個 <T> Future<T>,是表示任務等待完成的 Future.
public interface Callable<V>返回結果而且可能拋出異常的任務。實現者定義了一個不帶任何參數的叫作 call 的方法。
Callable 接口相似於 Runnable,二者都是爲那些其實例可能被另外一個線程執行的類設計的。可是 Runnable 不會返回結果,而且沒法拋出通過檢查的異常。
Executors 類包含一些從其餘普通形式轉換成 Callable 類的實用方法。
Callable中的call()方法相似Runnable的run()方法,就是前者有返回值,後者沒有。
當將一個Callable的對象傳遞給ExecutorService的submit方法,則該call方法自動在一個線程上執行,而且會返回執行結果Future對象。
一樣,將Runnable的對象傳遞給ExecutorService的submit方法,則該run方法自動在一個線程上執行,而且會返回執行結果Future對象,可是在該Future對象上調用get方法,將返回null.
package javaBasic; import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; public class CallableDemo { public static void main(String[] args) { // get available Processors int numberOfThreads = java.lang.Runtime.getRuntime() .availableProcessors(); ExecutorService executorService = Executors .newFixedThreadPool(numberOfThreads); List<Future<String>> resultList = new ArrayList<Future<String>>(); // create ten tasks for (int i = 0; i < 10; i++) { // use ExecutorService to execute taks of Callable Type, and save // result into future. Future<String> future = executorService .submit(new TaskWithResult(i)); // task result save into List resultList.add(future); } // Traversal Task for (Future<String> fs : resultList) { try { // print every thread result System.out.println(fs.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } finally { executorService.shutdown(); } } } } class TaskWithResult implements Callable<String> { private int id; public TaskWithResult(int id) { this.id = id; } public String call() throws Exception { System.out.println(System.currentTimeMillis() + " Start call() invoked " + id + " " + Thread.currentThread().getName()); // for (int i = 9999999; i > 0; i--) // ; Thread.sleep(5000); return System.currentTimeMillis() + " End call() invoked " + id + " " + Thread.currentThread().getName(); } }
線程池能夠解決兩個不 同問題:因爲減小了每一個任務調用的開銷,它們一般能夠在執行大量異步任務時提供加強的性能,而且還能夠提供綁定和管理資源(包括執行集合任務時使用的線 程)的方法。每一個 ThreadPoolExecutor 還維護着一些基本的統計數據,如完成的任務數。