java thread的stop,suspend,resume等方法废弃的原因

如下是官方文档,先贴上,抽时间翻译

Java

Why Are Thread.stopThread.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 exceptionThreadDeath 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:

  1. 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.
  2. 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 throwoperation, 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 startstop 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.


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值