您的位置:首页 > 编程语言 > Java开发

[置顶] java thread的stop,suspend,resume等方法废弃的原因

2016-12-23 09:23 375 查看
如下是官方文档,先贴上,抽时间翻译


Why Are 
Thread.stop
Thread.suspend

Thread.resume
 and 
Runtime.runFinalizersOnExit
 Deprecated?

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
 exception propagates up the stack.) If any of
the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can
result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, 
ThreadDeath
 kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest
itself at any time after the actual damage occurs, even hours or days in the future.

为什么thread.stop被废弃了呢?

因为它是天生不安全的。停止一个线程会导致它解锁它所锁定的所有monitor(当一个ThreadDeath Exception沿着栈向上传播时会解锁monitor),如果这些被释放的锁所保护的objects有任何一个进入一个不一致的状态,其他将要访问该objects的线程也会以一种不一致的状态来访问这些objects。这种objects称为“被损坏了”。当线程对被损坏的objects上做操作时,可能会产生意想不到的结果,这些行为可能是很严重的,并且难以探测到,

不像其他 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 the 
catch
 or 
finally
 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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: