Java併發程式設計系列之六:stop()、resume()和suspend()
這三個方法已經是jdk是過期的方法,為什麼仍然要單獨拿出來說呢?主要目的是理解jdk多執行緒API設計的初衷,理解並且更好使用執行緒API。那麼就來說說這三個方法吧:stop方法用於終止一個執行緒的執行,resume方法用於恢復執行緒的執行,suspend方法用於暫停執行緒的執行。要注意的resume方法需要和suspend方法配對使用,因為被暫停的執行緒需要執行恢復方法才能繼續執行。
雖然這三個方法不在推薦使用,但是作為學習,我們可以深入研究下這三個方法的作用以及為什麼不再推薦使用。
下面的程式碼首先建立一個列印執行緒,該執行緒完成的工作是每隔一秒鐘列印當前時間,然後由主執行緒對該列印執行緒進行停止、暫停和恢復操作。
package com.rhwayfun.concurrency;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* Created by rhwayfun on 16-4-2.
*/
public class DeprecatedThreadMethod {
public static void main(String[] args) throws InterruptedException {
DateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread printThread = new Thread(new Runner(),"PrintThread");
//設為守護執行緒
printThread.setDaemon(true);
//開始執行
printThread.start();
//休眠3秒,也就是PrintThread運行了3秒
TimeUnit.SECONDS.sleep(3);
//嘗試暫停
printThread.suspend();
System.out.println("main thread suspend PrintThread at " + format.format(new Date()));
TimeUnit.SECONDS.sleep(3);
//將PrintThread進行恢復,繼續輸出內容
printThread.resume();
System.out.println("main thread resume PrintThread at " + format.format(new Date()));
TimeUnit.SECONDS.sleep(3);
//嘗試終止PrintThread,停止輸出內容
printThread.stop();
System.out.println("main thread stop PrintThread at " + format.format(new Date()));
TimeUnit.SECONDS.sleep(3);
}
/**
* 該任務實現每隔一秒列印資訊
*/
static class Runner implements Runnable{
public void run() {
DateFormat format = new SimpleDateFormat("HH:mm:ss");
while (true){
System.out.println(Thread.currentThread().getName() + " run at " + format.format(new Date()));
//休眠一秒後繼續列印
SleepUtil.second(1);
}
}
}
}
執行結果如下:
可能你會很驚訝,這與我們設想的輸出結果如出一轍:首先列印執行緒執行3秒後,主執行緒暫停列印執行緒的執行,暫停3秒後,主執行緒正確地恢復了列印執行緒的執行,列印執行緒重新執行3秒後,主執行緒停止了列印執行緒的執行,程式結束。
我們可以看到,時間上還是完全吻合的,那麼如此好用的方法為什麼就不再推薦使用了呢?我們看看官方怎麼說:
This method has been deprecated, as it is inherently deadlock-prone. If the target thread holds a lock on the monitor protecting a critical system resource when it is suspended, no thread can access this resource until the target thread is resumed. If the thread that would resume the target thread attempts to lock this monitor prior to calling
resume
, deadlock results. Such deadlocks typically manifest themselves as “frozen” processes.
簡單地說主要是:suspend方法為例,該方法容易導致死鎖,因為該執行緒在暫停的時候仍然佔有該資源,這會導致其他需要該資源的執行緒與該執行緒產生環路等待,從而造成死鎖。stop方法同樣如此,該方法在終結一個執行緒時不會保證執行緒的資源正常釋放,通常是沒有給予執行緒完成資源釋放工作的機會,因此會導致程式在可能在工作狀態不確定的情況下工作。