A 調度執行線程單元的三種形式Thread,Runnable實現run()方法,Callable實現 T call()有返回值。
B Runnable,可以被Thread包裝,啓動線程執行,也能被ExecutorService調度;Callable只能用ExecutorService作爲調度容器。
C Future 主要用於查看任務進行的狀態(isDone()任務是否完成),結果。使用get()方法獲取結果時,當前線程處於阻塞狀態(如果任務中拋出異常,get()方法也會出現異常)。
D FutureTask,是Future和Runnable,Callable的混合體。
代碼演示
public static void main(String[] args) {
// 創建一個執行任務的服務
ExecutorService executor = Executors.newFixedThreadPool(3);
try {
//1.Runnable通過Future返回結果爲空
//創建一個Runnable,來調度,等待任務執行完畢,取得返回結果
Future<?> runnable1 = executor.submit(new Runnable() {
@Override
public void run() {
System.out.println("runnable1 running.");
}
});
System.out.println("Runnable1:" + runnable1.get());
// 2.Callable通過Future能返回結果
//提交併執行任務,任務啓動時返回了一個 Future對象,
// 如果想得到任務執行的結果或者是異常可對這個Future對象進行操作
Future<String> future1 = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
return "result=task1";
}
});
// 獲得任務的結果,如果調用get方法,當前線程會等待任務執行完畢後才往下執行
System.out.println("task1: " + future1.get());
//3. 對Callable調用cancel可以對對該任務進行中斷
//提交併執行任務,任務啓動時返回了一個 Future對象,
// 如果想得到任務執行的結果或者是異常可對這個Future對象進行操作
Future<String> future2 = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
try {
while (true) {
System.out.println("task2 running.");
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Interrupted task2.");
}
return "task2=false";
}
});
// 等待5秒後,再停止第二個任務。因爲第二個任務進行的是無限循環
Thread.sleep(10);
System.out.println("task2 cancel: " + future2.cancel(true));
// 4.用Callable時拋出異常則Future什麼也取不到了
// 獲取第三個任務的輸出,因爲執行第三個任務會引起異常
// 所以下面的語句將引起異常的拋出
Future<String> future3 = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
throw new Exception("task3 throw exception!");
}
});
System.out.println("task3: " + future3.get());
} catch (Exception e) {
System.out.println(e.toString());
}
// 停止任務執行服務
executor.shutdownNow();
}
運行結果:
runnable1 running.
Runnable1:null
task1: result=task1
task2 running.
task2 cancel: true
Interrupted task2.
java.util.concurrent.ExecutionException: java.lang.Exception: task3 throw exception!
public static void main(String[] args){
Callable<String> task = new Callable<String>() {
public String call() {
System.out.println("Sleep start.");
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Sleep end.");
return "time=" + System.currentTimeMillis();
}
};
//直接使用Thread的方式執行
FutureTask<String> ft = new FutureTask<String>(task);
Thread t = new Thread(ft);
t.start();
try {
System.out.println("waiting execute result");
System.out.println("result = " + ft.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//使用Executors來執行
System.out.println("=========");
FutureTask<String> ft2 = new FutureTask<String>(task);
Executors.newSingleThreadExecutor().submit(ft2);
try {
System.out.println("waiting execute result");
System.out.println("result = " + ft2.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
運行結果:
waiting execute result
Sleep start.
Sleep end.
result = time=1474442997863
=========
waiting execute result
Sleep start.
Sleep end.
result = time=1474443007864