線程是運行中的程序的調度單位,多線程問題可以理解爲多任務的並行處理問題,因此更多牽涉同步和異步問題;
進程與線程的區別
進程擁有自己的一整套變量,線程需要共享變量。
線程的實現方法
第一種實現方法
(1)創建一個Runnable對象;
(2)用Runnable對象創建一個線程;
(3)啓動線程;
Runnable runnable = new Runnable({
@Override
public void run() {
System.out.println("finish---in ---runnable");
}
});
Thread thread = new Thread(runnable);
thread.start();
第二種實現方法
(1)新建一個繼承於Thread的類MyThread
(2)新建一個MyThread對象;
(3)啓動線程;
MyThread.java
public class MyThread extends Thread{
String tag;
public MyThread(String tag) {
this.tag = tag;
}
@Override
public void run() {
System.out.println("finish---in ---" + tag);
}
}
MyThread myThread = new MyThread("MyThread");
myThread.start();
第三種實現方法
(1)新建一個實現了Runnable的接口MyRunnable;
(2)用新建的Runable對象新建一個MyThread對象;
(3)啓動線程;
MyRunnable.java
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("finish---in ---MyRunnable");
}
}
Thread thread = new Thread(new MyRunnable(){});
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.start();
第四種實現方法
(1)使用Callable接口和FutureTask創建線程;創建實現Callable接口的類,並實現call();
(2)使用FutureTask類包裝callable實現類的對象,最後將FutureTask對象作爲Thread對象的
target;
(3)啓動線程;
FutureTask<Integer> ft =
new FutureTask<Integer>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 10;
}
});
Thread thread = new Thread(ft);
thread.start();
try {
Integer value = ft.get(1000, TimeUnit.MILLISECONDS);
System.out.println(value.toString());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
FutureTask
一個FutureTask可以用來包裝一個Callable或Runnable對象. 因爲FutureTask實現了Runnable接口, a一個FutureTask能夠被提交到Executor去執行。
第五種方法
(1)使用Runnable和FutureTask創建線程;
(2)將FutureTask對象作爲Thread對象的target;
(3)啓動線程;
FutureTask<Integer> ft =
new FutureTask<Integer>(new MyRunnable(),100);//第二個參數是返回值和<?>對應類型
Thread thread = new Thread(ft);
thread.start();
try {
Integer value = ft.get(1000, TimeUnit.MILLISECONDS);
System.out.println(value.toString());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
區分Runnable,Callable,Future
Runnable
無返回值的異步任務
Callable
有返回值的異步任務,這是一個功能性接口,因此一個lambda表達式或方法參考可以作爲賦值的目標。
一個task,可能返回一個結果,也可能會拋出一個異常;實現該接口的類定義一個不帶參數的方法call,Callable接口類似於Runnable,都是設計給可能被另一個線程執行的類的實例。Runnable沒有返回值,也不會拋出一個已檢查異常。
Future
用來代表異步計算的結果。提供方法以檢查計算是否完成,等待其完成,並檢索計算結果。只有當計算完成時,才能得到結果,如果必要的話,就讓它處於阻塞態,直到它到達就緒態。取消通過取消方法執行。提供其他方法以確定任務是否正常完成或被取消。一旦計算完成,計算不能被取消。如果你想用Future爲了可取消性但是爲了提供一個可用的結果, 你可以聲明Future