JAVA多執行緒入門(二):JAVA中如何寫多執行緒
第一種方式:繼承Thread
步驟:
1.建立執行緒類,繼承自Thread + 重寫run,run中寫執行緒體,執行緒體就是mian()函式裡面的寫法
2.使用執行緒:
2.1 建立執行緒物件
2.2 執行緒物件.start()
步驟展示:
1.
public class Rabbit extends Thread {//執行緒類,繼承自Thread @Override public void run() {//在IDEA中可以通過ctrl+o快捷鍵快速重寫父類函式 super.run(); for(int i=0;i<1000;i++){ System.out.println("兔子跑了"+i+"步"); } } }
2.
public class RabbitAPP {
public static void main(String[] args){
Rabbit rabbit = new Rabbit();//2.1 建立物件
rabbit.start();//只是加到執行緒組裡面,等待CPU呼叫。CPU是自動呼叫的,所以不需要你自己寫程式。
//注意,不要呼叫run方法。如果你呼叫run方法,相當於是呼叫函式而已,沒有用到執行緒方面的內容。
}
}
第二種方式:通過Runnable介面
為什麼有了第一種方式還要使用第二種方式呢?因為Java只支援單繼承,如果一個類必須繼承自A類,那就無法繼承Thread類,所以必須實現介面來實現多執行緒。
步驟:
1.類實現Runnable介面+重寫run() ------->真實角色類
2.使用執行緒
2.1 建立真實角色
2.2 建立代理(Thread類)
2.3 代理.start()
這裡用到了代理設計模式,你可以先了解一下,基本來說代理設計模式就是:
1.真實類與代理類實現共同介面。
2.代理類中含有真實類引用,並且呼叫真實類方法。
總結來說就是代理類間接行使真實類的方法。
為什麼要這麼做呢?你看,哪怕是通過介面,最後還不是要通過Thread類來呼叫.start()?換句話說,當我們不想或者無法從Thread中繼承出類,但是我們還得用Thread類的時候,那我們應該怎麼辦?
我們應該,想辦法將我們寫的類和Thread之間構建一個關係。怎麼構建關係?把我們寫的類當做一個引數傳遞進去不就好了麼。但是問題又來了,我們是把類傳遞進去了,但是類的寫法多樣,實現功能也大相徑庭,憑什麼去保證你的類作為引數傳遞進Thread的時候,能恰好合適呢?哦,我們可以讓他們按照某種規範,或者某種準則。等等,規範?準則?那我懂了,介面!只要讓Thread和我們寫的類都派生於同一個介面不就好了麼?然後在這個接口裡寫上至少一個必須重寫的函式。這樣,當我們寫的類傳遞進Thread類的時候,Thread會在內部呼叫我們的run()函式,而我們無需關係Thrad在內部做了些什麼,豈不美哉?
好了,下面給出例項程式碼:
1.
package com.njust.MyThread;
public class Programmer implements Runnable {
@Override
public void run() {
for(int i=0;i<1000;i++)
System.out.println("一邊敲程式碼");
}
}
2.
package com.njust.MyThread;
public class ProgrammerApp {
public static void main(String[] args){
Programmer programmer = new Programmer();
Thread proxy = new Thread(programmer);
proxy.start();
for(int i=0;i<1000;i++)
System.out.println("一邊聊QQ");
}
}
第三種方式:通過Callable介面
好處是可以返回值,也能丟擲異常。Callable時Runnable的加強版。
1.建立Callable實現類+重寫call
2.藉助 執行排程服務 ExecutorService,獲取Future物件
ExecutorService ser = Executors.newFixedThreadPool(n);//n代表開啟多少個執行緒
Future result = ser.submit(實現類物件)
3.獲取值reslut.get();
4.停止服務ser.shutdownNow();
package com.njust.MyThread;
import java.util.concurrent.*;
public class Call {
public static void main(String[] args){
ExecutorService executorService = Executors.newFixedThreadPool(1);
Race racer = new Race();
Future<Integer> res = executorService.submit(racer);
int num = 0;
try {
num = res.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
executorService.shutdownNow();
System.out.println(num);
}
}
class Race implements Callable<Integer> {//這裡的泛型是返回值型別
@Override
public Integer call() throws Exception {
return 1000;
}
}