1.創(chuàng)建并啟動(dòng)線程的四種方式:
1)繼承Thread類創(chuàng)建線程
2)實(shí)現(xiàn)Runnable接口創(chuàng)建線程
3)使用Callable和Future創(chuàng)建線程
4)使用線程池,例如用Executor框架
2.使用Callable和Future創(chuàng)建線程的實(shí)現(xiàn)步驟:
- 1.定義一個(gè)Callable接口的實(shí)現(xiàn)類
- 2.創(chuàng)建Callable實(shí)現(xiàn)類對(duì)象傳遞給FutureTask構(gòu)造器
- 3.將FutureTask對(duì)象傳遞給Thread構(gòu)造器
- 4.Thread對(duì)象調(diào)用start方法啟動(dòng)線程
- 5.調(diào)用FutureTask對(duì)象的get方法獲取線程運(yùn)行的結(jié)果
3.需求:使用2個(gè)線程異步計(jì)算1-1000,000內(nèi)之和
實(shí)現(xiàn)代碼:
public class CallableDemo {
public static void main(String[] args) throws Exception {
//1.創(chuàng)建并啟動(dòng)線程
Callable<Integer> call1 = new CallableImpl(0, 50000);
Callable<Integer> call2 = new CallableImpl(50001, 100000);
FutureTask<Integer> f1 = new FutureTask<>(call1);
FutureTask<Integer> f2 = new FutureTask<>(call2);
new Thread(f1).start();
new Thread(f2).start();
//2.獲取每一個(gè)線程的結(jié)果
int ret1 = f1.get();
int ret2 = f2.get();
int ret= ret1+ret2;
System.out.println(ret);
}
}
class CallableImpl implements Callable<Integer>{
private int min;
private int max;
public CallableImpl(int min, int max) {
this.min = min;
this.max = max;
}
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = min; i <= max; i++) {
sum+=i;
}
return sum;
}
}
4.Callable和Runnable的區(qū)別如下:
1)Callable定義的方法是call,而Runnable定義的方法是run。
2)Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。
3)Callable的call方法可拋出異常,而Runnable的run方法不能拋出異常。
注意:
1.FutureTask為Runnable的實(shí)現(xiàn)類
2.FutureTask可以視為一個(gè)閉鎖,因?yàn)橹挥挟?dāng)線程運(yùn)行完才會(huì)出現(xiàn)結(jié)果。