時刻保持學習之心,方能成就不世功業
在學習Java的階段中,我們會遇到對以後影響深的多線程的使用,今天就為小夥伴們,帶來關于Java多線程的實作的三種方式:
1> 繼承Thread類,實作多線程;
在使用Thread開始多線程時,我們需要自定義類通過繼承Thread類,來實作重寫run() 方法;在啟動線程中又要其他二者不同,我們直接通過執行個體來展示:
public class TestThread extends Thread {
@Override
// run方法線程體
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("我是副線程--->"+i);
}
}
public static void main(String[] args) {
// 建立一個線程對象
TestThread testThread = new TestThread();
// 調用start()方法開啟線程
testThread.start();
for (int i = 0; i < 200; i++) {
System.out.println("我是主線程--->"+i);
}
// 二者是同時進行的,,會發生CPU的資源搶奪
// 線程開啟不一定執行,是由cpu決定的
2> 實作Runnable接口,實作多線程
Runnable接口實作線程是通過自定義的類去實作(implement) Runnable接口,同上也是需要重寫run()方法,但是在啟動線程執行時,需要使用Thread類來代理實作;此處我們通過代碼來了解:
//實作Runnable接口
public class TestRunnable implements Runnable{
@Override
public void run() {
// 重寫run()方法
for (int i = 0; i < 100; i++) {
System.out.println("執行了副線程"+i);
}
}
// 通過在主線程開啟線程的執行
public static void main(String[] args) {
TestRunnable t1 = new TestRunnable();
Thread thread = new Thread(t1);
thread.start();
for (int i = 0; i < 150; i++) {
System.out.println("執行了main線程"+i);
}
}
}
3> 總結---->繼承Thread類和實作Runnable接口,開啟多線程的方式的不同,二者的優缺點:
- 二者都是多線程的實作方式之一,他們都需要被某個類實作(Runnable)和繼承(Thread);
- 繼承Thread類和實作Runnable接口都具備有多線程的能力;
- 啟動線程———Thread----->需要子類對象.start()方法(調用start對象實作線程的開啟);Runnable----->new 實作類傳入目标對象---->Thread對象.start()方法來實作;二者開啟線程的方式不同
- 局限性:由于Thread屬于繼承類才能使用,但是在java中隻允許出現單繼承,具有一定的局限性,而在具體的使用過程中我們一般都使用Runnable接口實作,這樣有利于避免單繼承的局限性,友善同一個對象可以被線程使用;
- 由于局限性在更多的實際應用中,我們更多還是使用Runnable來實作多線程
- 繼承Thread的啟動線程:
TestThread testThread = new TestThread(); // 調用start()方法開啟線程 testThread.start();
- 實作Runnable的啟動線程
TestRunnable t1 = new TestRunnable();
Thread thread = new Thread(t1);
thread.start();
>4 實作Callable接口
Callable:接口是實作建立線程的又一種方法,他與Runnable接口和Thread類有很大的差別;
- 實作callable接口需要有傳回類型;
- 在重寫call方法,需要抛出異常;
- 建立目标對象:
-
建立執行服務:ExecutorService service = Executors.newFixedThreadPool(1);
newFixedThreadPool(nThread:線程的數量);
- 送出執行:Future result1 = service.submit(t1);
- 擷取結果:boolean r1 = result1.get();
- 關閉服務:service.shutdownNow();