目錄
1.概述
2.Thread的常見構造方法
3.Thread的幾個常見屬性
?4.啟動一個線程-start()
5.中斷一個線程
5.1通過共享的標記來進行溝通
5.2?調用 interrupt() 方法來通知
6.等待一個進程
?7.獲取當前線程引用
8.線程的狀態
8.1所有狀態
8.2線程狀態和轉移的意義
1.概述
Thread是jvm用來管理線程的一個類,即,在Java中,每個線程都有一個唯一的Thread對象與之關聯。
每個執行流,也需要有一個對象來描述,類似下圖所示,而 Thread 類的對象
就是用來描述一個線程執行流的,JVM 會將這些 Thread 對象組織起來,用于線程調度,線程管理
2.Thread的常見構造方法
方法 | 說明 |
Thread() | 創建線程對象 |
Thread(Runnable target) | 使用 Runnable 對象創建線程對象 |
Thread(String name) | 創建線程對象,并命名 |
Thread(Runnable target, String name) | 使用 Runnable 對象創建線程對象,并命名 |
3.Thread的幾個常見屬性
屬性 | 獲取方法 |
ID | getId() |
名稱 | getName() |
狀態 | getState() |
優先級 | getPriority() |
是否后臺線程 | isDaemon() |
是否存活 | isAlive() |
是否被中斷 | isInterrupted() |
?4.啟動一個線程-start()
之前我們已經看到了如何通過覆寫 run 方法創建一個線程對象,但線程對象被創建出來并不意味著線程就開始運行了。
覆寫 run 方法是提供給線程要做的事情的指令清單線程對象可以認為是把 李四、王五叫過來了
而調用 start() 方法,就是喊一聲:”行動起來!“,線程才真正獨立去執行了。
調用 start 方法, 才真的在操作系統的底層創建出一個線程.即,run方法是一個行動指南,而真正讓這個線程創建并執行出來的,是strat()方法。
?
5.中斷一個線程
?對于正在run方法中執行的線程,我們一般有兩種方法來中斷;
5.1通過共享的標記來進行溝通
?
public class demo3 {public static boolean quit;public static void main(String[] args) throws InterruptedException {Thread t = new Thread(()->{while (!quit){System.out.println("線程在執行...");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();Thread.sleep(5000);System.out.println("結束線程");quit=true;}
}
5.2?調用 interrupt() 方法來通知
public class demo3 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(()->{while (!Thread.currentThread().isInterrupted()){System.out.println("線程在執行...");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();Thread.sleep(5000);System.out.println("結束線程");t.interrupt();}
}
1. 如果線程因為調用 wait/join/sleep 等方法而阻塞掛起,則以 InterruptedException 異常的形式通
知,清除中斷標志,當出現 InterruptedException 的時候, 要不要結束線程取決于 catch 中代碼的寫法. 可以選擇忽略這個異常, 也可以跳出循環結束線程.
2.否則,只是內部的一個中斷標志被設置,t可以通過Thread.interrupted() 判斷當前線程的中斷標志被設置,清除中斷標志Thread.currentThread().isInterrupted() 判斷指定線程的中斷標志被設置,不清除中斷標志這種方式通知收到的更及時,即使線程正在 sleep 也可以馬上收到。
6.等待一個進程
有時,我們需要等待一個線程完成它的工作后,才能進行自己的下一步工作。這時我們需要一個方法明確等待線程的結束
方法 | 說明 |
public void join() | 等待線程結束 |
public void join(long millis) | 等待線程結束,最多等 millis 毫秒 |
public void join(long millis, int nanos) | 同理,但可以更高精度 |
import java.util.Random;public class demo1 {public static int tmp1;public static int tmp2;public static void main(String[] args) throws InterruptedException {int[] array = new int[10000000];Random random = new Random();for (int i = 0; i < array.length; i++) {int n = random.nextInt(100);array[i] = n;}long time1 = System.currentTimeMillis();Thread t1 = new Thread(()->{for (int i = 0; i < array.length; i+=2) {tmp1+=array[i];}});Thread t2 = new Thread(() ->{for (int i = 1; i < array.length; i+=2) {tmp2+=array[i];}});t1.start();t2.start();t1.join();t2.join();System.out.println("數組中的隨機數總和="+(tmp1+tmp2));long time2 = System.currentTimeMillis();System.out.println("程序運行時間=" + (time2-time1)+"ms" );}
}
如果把這兩個join注釋的話:
?7.獲取當前線程引用
方法 | 說明 |
public static Thread currentThread(); | 返回當前線程對象的引用 |
public static void main(String[] args) {Thread t = Thread.currentThread();System.out.println(t.getName());}