java thread的stop,suspend,resume等方法廢棄的原因
如下是官方文件,先貼上,抽時間翻譯
Why Are
|
Why is Thread.stop
deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath
ThreadDeath
為什麼thread.stop被廢棄了呢?
因為它是天生不安全的。停止一個執行緒會導致它解鎖它所鎖定的所有monitor(當一個ThreadDeath Exception沿著棧向上傳播時會解鎖
不像其他 uncheck exception,ThreadDeath Exception靜默的殺死程序,因此,使用者不會被警告他的程式會崩潰,這會在“損壞”之後的任何時候發生,甚至幾小時或者幾天後。
Couldn't I just catch the ThreadDeath
exception and fix the damaged object?
In theory, perhaps, but it would vastly complicate the task of writing correct multithreaded code. The task would be nearly insurmountable for two reasons:
- A thread can throw a
ThreadDeath
exception almost anywhere. All synchronized methods and blocks would have to be studied in great detail,with this in mind. - A thread can throw a second
ThreadDeath
exception while cleaning up from the first (in thecatch
orfinally
clause). Cleanup would have to repeated till it succeeded. The code to ensure this would be quite complex.
In sum, it just isn't practical.
我不能catch到這個ThreadDeath
exception 然後修復被損壞的object嗎
理論上,或許可以。但是它會極大地將多執行緒程式碼編寫複雜化,以下兩個原因,讓這項工作變得幾乎不可能完成:
1.一個執行緒會在幾乎任何地方丟擲ThreadDeath
exception,考慮到這一點,所有的同步方法和程式碼塊將必須進行詳細的考察
2.執行緒可能在處理第一個異常的時候(在catch,finally語句塊裡)丟擲第二個異常,處理語句必須將不得不重新開始反覆如此直到成功,來保證這一過程的程式碼將會非常複雜。
總結一下,這是不切實際的。
What about Thread.stop(Throwable)
?
In addition to all of the problems noted above, this method may be used to generate exceptions that its target thread is unprepared to handle (including checked exceptions that the thread could not possibly throw,
were it not for this method). For example, the following method is behaviorally identical to Java's throw
operation, but circumvents the compiler's attempts to guarantee that the calling method has declared all of the checked exceptions that it
may throw:
static void sneakyThrow(Throwable t) { Thread.currentThread().stop(t); }
那麼Thread.stop()方法是怎麼回事?
除了上邊提到的這些問題之外,這個方法會產生它的目標執行緒未準備好處理的異常(包括Checked exception,這種執行緒或許不會丟擲的異常),例如,下面的方法在行為上是與java的 Throwoperation相同的,但是規避了編譯器試圖保證該呼叫方法已經聲明瞭所有的它可能會丟擲的所有Checkd Exception的行為。
static void sneakyThrow(Throwable t) { Thread.currentThread().stop(t); }
What should I use instead of Thread.stop
?
Most uses of stop
should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return
from its run method in an orderly fashion if the variable indicates that it is to stop running. (This is the approach that the Java Tutorial has always recommended.) To ensure prompt communication of the stop-request, the variable must be volatile (or
access to the variable must be synchronized).
For example, suppose your applet contains the following start
, stop
and run
methods:
如果不用Thread.stop(),我們應該使用什麼方法?
大多數對stop方法的呼叫應該用指示目標執行緒是否應該停止執行的一些變數的簡單程式碼來替換,目標執行緒應該定時的檢查這些變數,當發現這些變數指示該執行緒應該停止執行時,有序地從它的run方法來return。(這是java tutorial中經常要求的方式)
private Thread blinker; public void start() { blinker = new Thread(this); blinker.start(); } public void stop() { blinker.stop(); // UNSAFE! } public void run() { Thread thisThread = Thread.currentThread(); while (true) { try { thisThread.sleep(interval); } catch (InterruptedException e){ } repaint(); } }You can avoid the use of
Thread.stop
by replacing the applet's stop
and run
methods
with:
private volatile Thread blinker; public void stop() { blinker = null; } public void run() { Thread thisThread = Thread.currentThread(); while (blinker == thisThread) { try { thisThread.sleep(interval); } catch (InterruptedException e){ } repaint(); } }
How do I stop a thread that waits for long periods (e.g., for input)?
That's what the Thread.interrupt
method is for. The same "state based" signaling mechanism shown above can be used, but the state change (blinker = null
, in the previous example) can be
followed by a call to Thread.interrupt
, to interrupt the wait:
public void stop() { Thread moribund = waiter; waiter = null; moribund.interrupt(); }For this technique to work, it's critical that any method that catches an interrupt exception and is not prepared to deal with it immediately reasserts the exception. We say reasserts rather than rethrows, because it is not always possible to rethrow the exception. If the method that catches the
InterruptedException
is
not declared to throw this (checked) exception, then it should "reinterrupt itself" with the following incantation:
Thread.currentThread().interrupt();This ensures that the Thread will reraise the
InterruptedException
as soon as it is able.
What if a thread doesn't respond to Thread.interrupt
?
In some cases, you can use application specific tricks. For example, if a thread is waiting on a known socket, you can close the socket to cause the thread to return immediately. Unfortunately, there really isn't
any technique that works in general. It should be noted that in all situations where a waiting thread doesn't respond to Thread.interrupt
, it wouldn't respond to Thread.stop
either. Such cases include deliberate denial-of-service
attacks, and I/O operations for which thread.stop and thread.interrupt do not work properly.