雖然java的API中說建立多線程的方式只有兩種(There are two ways to create a new thread of execution),分別是繼承Thread
類建立和實現Runnable
接口建立,在上一篇博文中演示了這兩種,詳見,可是JDK5.0之後新增了兩種,分別是實現Callable
接口建立和使用線程池
建立,本次就演示後兩種建立方式並分析其特性。html
Runnable
接口建立多線程建立步驟:java
1.建立一個實現Callable
接口的類。多線程
2.重寫call()方法,線程須要執行的代碼都放到call方法中。併發
3.建立實現Callable
接口類的實例對象。ide
4.將步驟 3 的對象做爲參數傳給FutureTask
構造器中,建立FutureTask
對象。性能
5.將FutureTask
的對象做爲參數傳給Thread
類,建立對象並調用start()方法。線程
package day02; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; //建立一個多線程,輸出20之內的偶數,並返回全部偶數的和 //1.建立一個實現`Callable`接口的類。 class TestSum implements Callable{ //2.重寫call()方法,線程須要執行的代碼都放到call方法中。 @Override public Object call() throws Exception{ int sum = 0; for(int i = 1;i <= 20 ;i++ ){ if(i % 2 == 0){ System.out.println(i); sum = sum + i; } } return sum; } } public class ThreadCall { public static void main(String[] args) throws ExecutionException, InterruptedException { //3.建立實現`Callable`接口類的實例對象。 TestSum test = new TestSum(); //4.將步驟 3 的對象做爲參數傳給`FutureTask`構造器中,建立`FutureTask`對象。 FutureTask futuretask = new FutureTask(test); //5.將`FutureTask`的對象做爲參數傳給`Thread`類,建立對象並調用start()方法。 Thread thread = new Thread(futuretask); thread.start(); //get方法能夠獲取返回值 System.out.println("偶數總合是:"+futuretask.get()); } } //輸出結果: 2 4 6 8 10 12 14 16 18 20 偶數總合是:110
實現Callable接口建立多線程的特色:code
1.call()方法能夠有返回值,能夠使用get()方法獲取返回值。htm
2.call()方法能夠拋出異常, 並且能被外面捕獲到。對象
3.Callable支持泛型。
package day02; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class Number implements Runnable{ @Override public void run() { for (int i = 0; i < 20; i++) { if (i % 2 == 0){ System.out.println(Thread.currentThread().getName()+":"+i); } } } } public class ThreadPool { public static void main(String[] args){ ExecutorService service = Executors.newFixedThreadPool(10); Number num = new Number(); service.execute(num); service.shutdown();
二.實現Callable接口的方式建立:
package day02; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class Number implements Callable { @Override public Object call() { for (int i = 0; i < 20; i++) { if (i % 2 == 0){ System.out.println(Thread.currentThread().getName()+":"+i); } } return null; } } public class ThreadPool { public static void main(String[] args){ ExecutorService service = Executors.newFixedThreadPool(10); Number num = new Number(); service.submit(num);//區別在這裏 service.shutdown(); } }
1.頻繁建立線程和銷燬使用量較大的資源,好比並發的線程,對性能影響較大,因此須要建立線 程池存放線程,使用的時候直接獲取,實現重複利用,提升效率。
2.下降建立線程時間,提升響應速度。
3.下降資源的消耗。
4.便於線程管理。