为什么 Thread.stop、Thread.suspend、Thread.resume、Runtime.runFinalizersOnExit 都被废弃了

最近一个同学发来消息说,公司里有一段代码使用的线程经常会发生一些莫名其妙的问题。让我帮忙看看,我仔细看了很多遍线程的相关代码。最后注意到了 InterruptException 异常,把想法和 demo 代码给他说了后,问题果真被解决了。

为什么 Thread.stop、Thread.suspend、Thread.resume、Runtime.runFinalizersOnExit 都被废弃了
危险代码

关于这个问题,我通过一段简化的代码来给大家演示一下。

public class ThreadSafe extends Thread {
    public void run() { 
        while (true){
            try{
                Thread.sleep(5*1000);//阻塞5妙
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    } 
}

看到上面这段 demo 了吗?多简单,多熟悉啊。但是有一个问题,90% 的人可能都没有遇到,但确实存在的。

我们先看 Thread.sleep 为什么要抛出一个异常?其实,很简单,你仔细想想,如果你正在睡觉的时候,突然有人打扰到你,是不是就相当于发生了中断睡觉的异常。而 InterruptedException 这个异常的发生就是因为有人打扰了这个线程的休眠。

谁打扰的呢?就是调用这个线程的 interrupt() 方法的对象。OK ,现在我们来看看,当我调用上面这个线程的 interrupt() 方法的时候,它正在休眠,那么就会发生 InterruptedException 异常。而这个时候,你却把 InterruptedException 异常捕捉了,于是本该停止的线程就行失去刹车的车辆一样裸奔了。

而正确的处理 InterruptedException 异常的方法是,捕捉异常之后,加一个 break,终止线程。除此之外,结束一个线程推荐的方法有 3 种。

public class ThreadSafe extends Thread {
    public volatile boolean exit = false; 
        public void run() { 
        while (!exit){// 1、标志位结束
            //do something
        }
        while (!isInterrupted()){//2、判断 interrupted 状态
            //do something, but no throw InterruptedException
        }
        while (!isInterrupted()){ //3、非阻塞过程中通过判断中断标志来退出
            try{
                Thread.sleep(5*1000);//阻塞过程捕获中断异常来退出
            }catch(InterruptedException e){
                e.printStackTrace();
                break;//捕获到异常之后,执行break跳出循环。
                // 或者使用下面的代码
                // 重新设置中断标志位 
                Thread.currentThread().interrupt();
            }
        }
    } 
}

现在我们再来看看为什么 Thread.stop、Thread.suspend、Thread.resume、Runtime.runFinalizersOnExit 这几个方法都被废弃了。这是因为,这几个操作太暴力了。stop() 方法会真的杀死线程,不给线程喘息的机会,如果线程持有 ReentrantLock 锁,被 stop() 的线程并不会自动调用 ReentrantLock 的 unlock() 去释放锁,那其他线程就再也没机会获得 ReentrantLock 锁,这实在是太危险了。所以该方法就不建议使用了,类似的方法还有 suspend() 和 resume() 方法、Runtime.runFinalizersOnExit() 方法,这 3 个方法同样也都不建议使用了。危害性都非常大,所以被废弃的方法你千万不要使用!

为什么 Thread.stop、Thread.suspend、Thread.resume、Runtime.runFinalizersOnExit 都被废弃了

: » 为什么 Thread.stop、Thread.suspend、Thread.resume、Runtime.runFinalizersOnExit 都被废弃了

原创文章,作者:wdmbts,如若转载,请注明出处:https://blog.ytso.com/252107.html

(0)
上一篇 2022年5月4日
下一篇 2022年5月4日

相关推荐

发表回复

登录后才能评论