繼Java執行緒生命週期繼續學習Java執行緒其他常用操作
執行緒的常用操作
設定執行緒名字:setName()
獲取執行緒名稱:getName()
執行緒唯一Id:getId()
// 自定義執行緒名稱
String threadName = "threadName";
// 構造方法方式
Thread thread = new Thread(() -> {
System.out.println("執行緒名=" + Thread.currentThread().getName());
},threadName);
// set方法方式// thread.setName(threadName);
System.out.println("執行緒唯一Id=" + thread.getId());
執行緒啟動:start()
判斷執行緒是否存活:isAlive()
// 執行緒啟動
thread.start();
System.out.println("是否為存活執行緒=" + thread.isAlive());
執行緒方法:run() /call()
執行緒啟動後會去呼叫的方法。執行緒要做什麼就在run/call方法寫,不需要直接呼叫,執行緒啟動後自己會去呼叫run() /call()。如果程式沒有啟動執行緒直接呼叫run/call,那麼就不屬於多執行緒程式設計,是屬於當前執行緒直接呼叫普通方法一樣。
獲取當前執行緒物件:currentThread()
操作當前執行緒的非static方法,得先拿到執行緒物件才可以
// 獲取當前執行緒物件
Thread currentThread = Thread.currentThread();
// 對當前執行緒做一些操作
System.out.println(currentThread.getName());
try {
// sleep 靜態方法則不需要
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
關於執行緒的狀態控制(生命週期)的操作可以參考上一篇文章。
守護執行緒(後臺執行緒)
普通執行緒(使用者執行緒)的守護者,守護執行緒的任務是為其他的執行緒提供服務。如果程式中沒有了使用者執行緒,那麼守護執行緒也就沒有存在的意義,JVM也隨之結束。典型的守護執行緒有JVM的垃圾回收執行緒,作業系統的啟動也會啟動各種模組的守護執行緒。
設定執行緒為守護執行緒:setDaeman()
注意:該方法必須在start() 方法之前呼叫
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("執行緒名="+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 這一句不會列印出來,因為main執行緒(目前唯一的普通執行緒)等待1秒後已經結束了
System.out.println("守護執行緒的狀態=" + Thread.currentThread().getState());
});
// 守護執行緒
thread.setDaemon(true);
// 執行緒啟動
thread.start();
System.out.println("是否為守護執行緒=" + thread.isDaemon());
}
執行緒序列化
執行join() 方法的執行緒進入等待喚醒狀態(WAITING),直到呼叫該方法的執行緒結束後再由等待喚醒狀態轉為可執行狀態(RUNNABLE)。join() 方法是Thread類中的方法,其底層是使用wait() 方法來實現執行緒等待,待執行緒isAlive()為false 時才
實現執行緒的序列化:一個執行緒呼叫另一個執行緒物件的join() 來實現執行緒序列化執行。
舉個例子:一道好菜
public class DemoCooking {
public static void main(String[] args) {
Thread mainThread = Thread.currentThread();
// 1.買菜
Thread buyThread = new Thread(new CookingThread(mainThread,"買菜"),"buyThread");
// 2.洗菜
Thread washThread = new Thread(new CookingThread(buyThread,"洗菜"),"washThread");
// 3.切菜
Thread cutThread = new Thread(new CookingThread(washThread,"切菜"),"cutThread");
// 4.炒菜
Thread scrambleThread = new Thread(new CookingThread(cutThread,"炒菜"),"scrambleThread");
// 不受執行緒啟動順序的影響
scrambleThread.start();
washThread.start();
cutThread.start();
buyThread.start();
// main執行緒先執行完才可以開始:買菜
System.out.println("開始準備……");
}
public static class CookingThread implements Runnable{
private final Thread thread;
private final String job;
public CookingThread(Thread thread, String job){
this.thread = thread;
this.job = job;
}
@Override
public void run() {
String name = Thread.currentThread().getName()+":";
try {
thread.join();
System.out.println(name + job + "開始");
Thread.sleep(1000);
System.out.println(name + job + "結束");
Thread.sleep(1000); // 偷懶下
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
執行結果:main > buyThread > washThread > cutThread > scrambleThread > 結束
開始準備……
buyThread:買菜開始
buyThread:買菜結束
washThread:洗菜開始
washThread:洗菜結束
cutThread:切菜開始
cutThread:切菜結束
scrambleThread:炒菜開始
scrambleThread:炒菜結束
執行緒優先順序
設定當前執行緒的優先順序,執行緒優先順序越高,執行緒可能獲得執行的次數越多,Java執行緒的優先順序用整數表示,優先順序的範圍為1-10,預設為5。
setPriority(int)方法:設定執行緒的優先順序。
getPriority方法:獲取執行緒的優先順序。
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("執行緒1");
});
thread.setPriority(10);
Thread thread1 = new Thread(() -> {
System.out.println("執行緒2");
});
thread1.setPriority(1);
thread.start();
thread1.start();
System.out.println("執行緒預設的優先順序為=" + Thread.currentThread().getPriority());
}
執行緒中斷
使用interrupt() 方法設定執行緒中斷標誌=true,讓執行緒受到“阻塞”時丟擲一箇中斷訊號。如果執行緒處於阻塞、等待喚醒或超時等待狀態(Object.wait, Thread.join和Thread.sleep)時,那麼它將接收到一箇中斷異常(InterruptedException),從而提前被結束該狀態。反之,如果執行緒是處於“可執行”(RUNNABLE)狀態,那麼中斷標誌將沒有作用。
案例一:執行緒中斷有效
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("執行緒1");
try {
// 鬧鐘1分鐘後響
Thread.sleep(60000);
System.out.println("鬧鐘響了");
} catch (InterruptedException e) {
// 提前退出超時等待狀態
System.out.println("發生異常,提前醒了,鬧鐘沒響手動關了");
}
System.out.println("繼續執行該執行緒的後續程式……");
});
thread.setPriority(1);
thread.start();
thread.interrupt();
System.out.println("main執行緒將thread 終端狀態設定為 "+thread.isInterrupted());
}
執行結果:
main執行緒將thread 終端狀態設定為 true
執行緒1
發生異常,提前醒了,鬧鐘沒響手動關了
繼續執行該執行緒的後續程式……
案例二:執行緒中斷無效
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
System.out.println("執行緒" + Thread.currentThread().getName());
while (true) {
System.out.print(Thread.currentThread().getState() + "\t");
}
});
thread1.start();
thread1.interrupt();
}
執行結果:執行緒一直列印自己的狀態為RUNNABLE。
更多優質文章,請關注WX公眾號:Java全棧佈道師