Java多線程系列——過期的suspend()掛起、resume()繼續執行線程


簡述

這兩個操作就好比播放器的暫停和恢復。

但這兩個 API 是過期的,也就是不建議使用的。

不推薦使用 suspend() 去掛起線程的原因,是因為 suspend() 在導致線程暫停的同時,並不會去釋放任何鎖資源。其他線程都無法訪問被它占用的鎖。直到對應的線程執行 resume() 方法后,被掛起的線程才能繼續,從而其它被阻塞在這個鎖的線程才可以繼續執行。

但是,如果 resume() 操作出現在 suspend() 之前執行,那么線程將一直處於掛起狀態,同時一直占用鎖,這就產生了死鎖。而且,對於被掛起的線程,它的線程狀態居然還是 Runnable。

實例

 1 import java.util.concurrent.locks.LockSupport;
 2 /**
 3  * Created by zhengbinMac on 2017/3/3.
 4  */
 5 public class SuspendResumeTest {
 6     public static Object object = new Object();
 7     static TestThread t1 = new TestThread("線程1");
 8     static TestThread t2 = new TestThread("線程2");
 9     public static class TestThread extends Thread{
10         public TestThread(String name) {
11             super.setName(name);
12         }
13         @Override
14         public void run() {
15             synchronized (object) {
16                 System.out.println(getName()+" 占用。。");
17                 Thread.currentThread().suspend();
18 //                LockSupport.park();
19             }
20         }
21     }
22     public static void main(String[] args) throws InterruptedException {
23         t1.start();
24         Thread.sleep(200);
25         t2.start();
26         t1.resume();
27 //        LockSupport.unpark(t1);
28 //        LockSupport.unpark(t2);
29         t2.resume();
30         t1.join();
31         t2.join();
32     }
33 }

運行多次,可能出現下圖結果:

代碼執行流程,如下圖所示:

此時,通過 jps 和 jstack 命令,來觀察線程狀態,如下圖所示:

從輸出結果來看,線程 t2 其實是被掛起的,但是從上圖來看,它的線程狀態卻是 RUNNABLE,這會使我們誤判當前系統狀態。

參考資料

[1] 實戰Java高並發程序設計, 2.2.5 - 掛起(suspend)和繼續執行(resume)線程

[2] Java並發編程的藝術, 4.2.4 - 過期的suspend()、resume() 和 stop()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM