更新時間:2021-02-02 17:22:49 來源:動力節點 瀏覽1196次
線程(thread)是操作系統能夠進行運算調度的最小單位,也是獨立調度和分派的基本單位。線程作為計算機技術中十分重要的內容,線程是我們必須要掌握的重點知識。在線程中的許多操作,比如終止線程都是需要調用線程操作方法來實現的,本文我們通過一些實例來介紹這些線程操作方法。
我們比較熟悉的一些線程操作方法:
Thread.currentThread().getName();獲取當前運行線程的名字
suspend:暫停線程后不釋放鎖,容易造成死鎖
stop:線程被粗暴終結,的資源不能釋放
interrupt:通知線程可以結束,線程可以完全不理會, 結合isInterrupted使用
注意interrupted方法和isInterrupted的區別,前者會在調用后清除interrupted status,后者不會。
中斷線程不建議自主設置標志位,因為如果是通過判斷標志位進入線程sleep、wait、take等方法,線程被阻塞,就不會再判斷標志位,而使用interrupt就不會產生這樣的問題,因為他們可以自動監控線程中斷狀態。(如果是在runnable中想使用這個方法,就使用Thread.currentThread.isInterrupted即可)
使用interrupt中斷線程
public class HasInterruptException extends Thread {
????@Override
????public void run() {
????????super.run();
????????while (!isInterrupted()) {
????????????System.out.println(Thread.currentThread().getName() + "is running");
????????}
????????System.out.println(Thread.currentThread().getName() + "interrupt flag is " + isInterrupted());
????}
????public static void main(String[] args) {
????????HasInterruptException hasInterruptException = new HasInterruptException();
????????hasInterruptException.start();
????????try {
????????????Thread.sleep(400);
????????} catch (InterruptedException e) {
????????????e.printStackTrace();
????????}
????????hasInterruptException.interrupt();
????}
}
線程阻塞方法也可以監控線程interrput方法,如果處于阻塞狀態,會被程序檢測出來,并拋出interruptedException異常,同時將interrupt狀態恢復,但線程會繼續運行剩余的任務
public class HasInterruptException extends Thread {
????@Override
????public void run() {
????????super.run();
????????while (!isInterrupted()) {
????????????try {
????????????????sleep(500);
????????????} catch (InterruptedException e) {
????????????????e.printStackTrace();
????????????}
????????????System.out.println(Thread.currentThread().getName() + "is running");
????????????System.out.println(Thread.currentThread().getName() + "now interrupt state " + isInterrupted());
????????}
????????System.out.println(Thread.currentThread().getName() + "interrupt flag is " + isInterrupted());
????}
????public static void main(String[] args) {
????????HasInterruptException hasInterruptException = new HasInterruptException();
????????hasInterruptException.start();
????????try {
????????????Thread.sleep(400);
????????} catch (InterruptedException e) {
????????????e.printStackTrace();
????????}
????????hasInterruptException.interrupt();
????}
}
如果需要在有阻塞代碼時也能正常中斷線程,需要在阻塞方法檢查到中斷時再添加中斷方法,在interrupt()之前可以添加一些善后處理代碼
?@Override
????public void run() {
????????super.run();
????????while (!isInterrupted()) {
????????????try {
????????????????sleep(500);
????????????} catch (InterruptedException e) {
????????????????e.printStackTrace();
????????????????//如果需要在有阻塞代碼時也能正常中斷線程,需要在阻塞方法檢查到中斷時再添加中斷方法,在此之前可以添加一些善后處理代碼
????????????????interrupt();
????????????}
????????????System.out.println(Thread.currentThread().getName() + "is running");
????????????System.out.println(Thread.currentThread().getName() + "now interrupt state " + isInterrupted());
????????}
????????System.out.println(Thread.currentThread().getName() + "interrupt flag is " + isInterrupted());
????}
由此可知,阻塞方法中檢測到中斷會拋出異常到原因是為了提示程序這時候線程不能直接中斷,需要正確處理善后,再執行中斷。
start:Thread僅僅是一個線程相關類,new出來后不調用start方法是沒有開啟線程的。
start方法只能調用一次,多次調用會拋出IllegalThreadStateException異常
如果new一個Thread之后直接調用run方法,和調用一個普通方法效果完全一致,在主線程中執行。
yield:執行該方法的線程會讓出cpu的執行權,進入就緒狀態。不會釋放鎖,調用該方法后cpu可能還會重新選中該線程執行,所以這個方法不可靠。
join:讓調用該方法的線程執行完畢之后,其他線程才能執行,必須放在start之后。有三個重載方法,參考 Java Thread的join() 之刨根問底
static class A extends Thread {
????????@Override
????????public void run() {
????????????super.run();
????????????try {
????????????????Thread.sleep(2000);
????????????} catch (InterruptedException e) {
????????????????e.printStackTrace();
????????????}
????????????System.out.println(Thread.currentThread().getName() + " runing end");
????????}
????}
????public static void main(String[] args) {
????????A a = new A();
????????A aa = new A();
????????a.start();
????????aa.start();
????????try {
????????????aa.join();
????????} catch (InterruptedException e) {
????????????e.printStackTrace();
????????}
????}
setPriority:設置線程優先級,這個方法不完全可靠,也有一定效果
setDaemon(boolean)守護線程,當進程中所有線程都是守護線程時候,進程結束
守護線程因為用戶線程結束而被動結束時候,線程中的方法不一定能完全執行,如finally語句不一定能執行
notify()/notifyAll() 不會釋放鎖
注: wait(),notify(),notifyAll()應該放在synchronized關鍵字所保護的內容內,wait方法調用時調用方釋放鎖,但是notify/notifyAll調用時調用方需要在線程方法運行完畢之后才釋放鎖,所以notify/notifyAll一般會被放在同步代碼塊的最后一行。
wait() wait是指在一個已經進入了同步鎖的線程內,讓自己暫時讓出同步鎖,以便其他正在等待此鎖的線程可以得到同步鎖并運行,只有其他線程調用了notify方法(notify并不釋放鎖,只是告訴調用過wait方法的線程可以去參與獲得鎖的競爭了,但不是馬上得到鎖,因為鎖還在別人手里,別人還沒釋放。如果notify方法后面的代碼還有很多,需要這些代碼執行完后才會釋放鎖,可以在notfiy方法后增加一個等待和一些代碼),調用wait方法的線程就會解除wait狀態并爭搶cpu使用權,搶到了之后才會執行wait之后的代碼。可以指定停止的時間參數,也可不指定。
sleep() sleep就是正在執行的線程主動讓出cpu,cpu去執行其他線程,在sleep指定的時間過后,cpu才會回到這個線程上繼續往下執行,如果當前線程進入了同步鎖,sleep方法并不會釋放鎖,即使當前線程使用sleep方法讓出了cpu,但其他被同步鎖擋住了的線程也無法得到執行。當休眠時間到并跑完同步代碼之后才會釋放鎖。和wait一樣,調用時候都會把cpu資源讓出。
注:obj=null 只是表示這個引用不再指向該對象,不代表這個對象不存在了
?????PDD pp = new PDD();
????????PDD ppp = pp;
????????System.out.println(pp);
????????System.out.println(ppp);
????????pp = null;
????????System.out.println(pp);
????????System.out.println(ppp);
????????輸出
????????//com.example.annotation.PDD@6d06d69c
????????//com.example.annotation.PDD@6d06d69c
????????//null
????????//com.example.annotation.PDD@6d06d69c
想讓對象被垃圾回收機制回收,需要保證沒有強引用指向這個對象
注:線程同步阻塞的一個例子
@Override
????public void run() {
????????while (!Thread.currentThread().isInterrupted()) {
????????????System.out.println(Thread.currentThread().getName() + " start");
????????????synchronized (this) {
????????????????try {
????????????????????System.out.println(Thread.currentThread().getName() + "sleep start");
????????????????????Thread.sleep(5000);
????????????????} catch (InterruptedException e) {
????????????????????e.printStackTrace();
????????????????}
????????????????System.out.println(Thread.currentThread().getName() + "sleep end");
????????????}
????????????System.out.println(Thread.currentThread().getName() + " continue...");
????????}
????}
所有遇到同步代碼塊或者同步方法的線程都會被阻塞,除非搶到鎖,搶到鎖之后會繼續往下執行,而不會跳過同步代碼塊/同步方法再執行。
以上就是一些線程操作方法的實例講解,線程操作方法的掌握不僅僅是用來實現線程的各種操作,對于我們加深理解線程的工作原理和線程中的各種機制也有很大的幫助。在本站的多線程教程中,對線程的操作方法還有更多的解讀和介紹,感興趣想要在多線程領域學有所成的小伙伴不要錯過哦。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習