詳解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。
以上就是詳解Java線程中常用操作的詳細內容,更多關於Java線程操作的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- 一篇文章掌握Java Thread的類及其常見方法
- 新手瞭解java 多線程基礎知識
- Java多線程Thread類的使用及註意事項
- Java多線程之線程狀態詳解
- java多線程join()方法的作用和實現原理解析(應用場景)