線程的常用操作
設置線程名字: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線程操作的資料請關注html5模板網其它相關文章!