首先了解一下線程的五種狀態:
-
新建狀態:
新建狀態是指new之後,即新創建了一個線程的時候,此時並未運行任何線程方法體內· 的程序代碼。
-
就緒狀態:
簡單來說就是指程序調用了start()之後,線程就得到了啓動,代表線程進入了就緒狀態,但是此時並不代表它會立刻去執行run()方法體內的程序代碼,而是隨時等待cpu的調度。
-
運行狀態:
獲得cpu的時間後,調用run()方法,進入運行狀態。
-
阻塞狀態:
由於某種原因放棄了cpu的會用權力,暫時停止運行,等待再次被調用。
-
死亡狀態:
線程正常執行完畢,或者是中途出現了異常退出了run()。
-
繼承Thread類
最基本的實現多線程的方式,繼承Thread類,重寫run方法,通過start方法執行。
由於是繼承的關係,所以這種方式也就有了他的侷限性,只能有一個直接父類。
package cn.com.dh;
public class MyThread extends Thread{
@Override
public void run() {
System.out.println("myThread start...");
for(int i = 0; i < 30; i++){
System.out.println("第 "+i + " 次執行。。");
}
System.out.println("myThread end!!!");
}
public static void main(String[] args) {
System.out.println("main thread start...");
new MyThread().start();
System.out.println("main end!!!");
}
}
Console打印輸出
main thread start...
main end!!!
myThread start...
第 0 次執行。。
第 1 次執行。。
第 2 次執行。。
第 3 次執行。。
第 4 次執行。。
第 5 次執行。。
第 6 次執行。。
第 7 次執行。。
第 8 次執行。。
第 9 次執行。。
第 10 次執行。。
第 11 次執行。。
第 12 次執行。。
第 13 次執行。。
第 14 次執行。。
第 15 次執行。。
第 16 次執行。。
第 17 次執行。。
第 18 次執行。。
第 19 次執行。。
第 20 次執行。。
第 21 次執行。。
第 22 次執行。。
第 23 次執行。。
第 24 次執行。。
第 25 次執行。。
第 26 次執行。。
第 27 次執行。。
第 28 次執行。。
第 29 次執行。。
myThread end!!!
Process finished with exit code 0
- 實現runnable接口
因爲繼承的侷限性,所以我們一般不會去用繼承Thread類的方式去實現多線程,我們初級階段用到的最多的是實現runnable接口,重寫run方法,通過Thread調用start方法,進行線程的啓動。
package cn.com.dh;
public class MyThreadR implements Runnable {
@Override
public void run() {
for(int i = 0; i < 30; i++){
System.out.println("第 "+i+" 次執行"+Thread.currentThread().getName());
}
}
public static void main(String[] args) {
MyThreadR myThreadR1 = new MyThreadR();
MyThreadR myThreadR2 = new MyThreadR();
Thread thread1 = new Thread(myThreadR1);
Thread thread2 = new Thread(myThreadR2,"t2");
thread1.start();
thread2.start();
}
}
Console打印輸出
第 0 次執行Thread-0
第 1 次執行Thread-0
第 2 次執行Thread-0
第 3 次執行Thread-0
第 4 次執行Thread-0
第 5 次執行Thread-0
第 6 次執行Thread-0
第 7 次執行Thread-0
第 8 次執行Thread-0
第 9 次執行Thread-0
第 10 次執行Thread-0
第 11 次執行Thread-0
第 12 次執行Thread-0
第 13 次執行Thread-0
第 14 次執行Thread-0
第 0 次執行t2
第 15 次執行Thread-0
第 1 次執行t2
第 16 次執行Thread-0
第 2 次執行t2
第 17 次執行Thread-0
第 3 次執行t2
第 18 次執行Thread-0
第 4 次執行t2
第 19 次執行Thread-0
第 5 次執行t2
第 20 次執行Thread-0
第 6 次執行t2
第 21 次執行Thread-0
第 7 次執行t2
第 22 次執行Thread-0
第 8 次執行t2
第 23 次執行Thread-0
第 9 次執行t2
第 24 次執行Thread-0
第 10 次執行t2
第 25 次執行Thread-0
第 11 次執行t2
第 26 次執行Thread-0
第 12 次執行t2
第 27 次執行Thread-0
第 13 次執行t2
第 28 次執行Thread-0
第 14 次執行t2
第 29 次執行Thread-0
第 15 次執行t2
第 16 次執行t2
第 17 次執行t2
第 18 次執行t2
第 19 次執行t2
第 20 次執行t2
第 21 次執行t2
第 22 次執行t2
第 23 次執行t2
第 24 次執行t2
第 25 次執行t2
第 26 次執行t2
第 27 次執行t2
第 28 次執行t2
第 29 次執行t2
- 實現callable接口
此種方式於與之前的兩張方式最大的不同在於,實現callable接口可以有返回值和拋出異常
需要藉助服務,線程池和future類
package cn.com.dh;
import java.util.concurrent.*;
public class MyThreadC implements Callable<String> {
private String threadName;
@Override
public String call() throws Exception {
for(int i = 0; i < 20; i ++){
threadName = "第 " + i +" 次執行,"+ Thread.currentThread().getName();
System.out.println(threadName);
}
return threadName;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 創建實現類對象
MyThreadC myThreadC1 = new MyThreadC();
MyThreadC myThreadC2= new MyThreadC();
// 創建執行服務
ExecutorService executorService = Executors.newFixedThreadPool(2);
// 提交執行
Future<String> future1 = executorService.submit(myThreadC1);
Future<String> future2 = executorService.submit(myThreadC2);
// 獲取結果
String res1 = future1.get();
String res2 = future2.get();
// 關閉服務
executorService.shutdown();
}
}
Console打印輸出:
第 0 次執行,pool-1-thread-2
第 0 次執行,pool-1-thread-1
第 1 次執行,pool-1-thread-1
第 1 次執行,pool-1-thread-2
第 2 次執行,pool-1-thread-1
第 2 次執行,pool-1-thread-2
第 3 次執行,pool-1-thread-1
第 3 次執行,pool-1-thread-2
第 4 次執行,pool-1-thread-2
第 5 次執行,pool-1-thread-2
第 6 次執行,pool-1-thread-2
第 7 次執行,pool-1-thread-2
第 8 次執行,pool-1-thread-2
第 9 次執行,pool-1-thread-2
第 10 次執行,pool-1-thread-2
第 11 次執行,pool-1-thread-2
第 4 次執行,pool-1-thread-1
第 12 次執行,pool-1-thread-2
第 5 次執行,pool-1-thread-1
第 13 次執行,pool-1-thread-2
第 6 次執行,pool-1-thread-1
第 14 次執行,pool-1-thread-2
第 7 次執行,pool-1-thread-1
第 15 次執行,pool-1-thread-2
第 8 次執行,pool-1-thread-1
第 16 次執行,pool-1-thread-2
第 9 次執行,pool-1-thread-1
第 17 次執行,pool-1-thread-2
第 10 次執行,pool-1-thread-1
第 18 次執行,pool-1-thread-2
第 19 次執行,pool-1-thread-2
第 11 次執行,pool-1-thread-1
第 12 次執行,pool-1-thread-1
第 13 次執行,pool-1-thread-1
第 14 次執行,pool-1-thread-1
第 15 次執行,pool-1-thread-1
第 16 次執行,pool-1-thread-1
第 17 次執行,pool-1-thread-1
第 18 次執行,pool-1-thread-1
第 19 次執行,pool-1-thread-1
Process finished with exit code 0