我爱学Java之Thread中stop(),suspend(),resume()为什么不安全

当调用stop()方法时会发生两件事:

1.即刻停止run()方法中剩余的全部工作,包括在catch或finally语句中,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭。

2.会立即释放该线程所持有的所有的锁,导致数据得不到同步的处理,出现数据不一致的问题。

举个例子:

public class Main{
    public static void main(String [] args) throws Exception{
        TestObject testObject = new TestObject();
        Thread t1 = new Thread(){
            public void run(){
                try {
                    testObject.print("1", "2");
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };

        t1.start();
        Thread.sleep(1000);
        t1.stop();
        System.out.println("first : " + testObject.getFirst() + " " + "second : " + testObject.getSecond());


    }
}

class TestObject{
    private String first = "ja";
    private String second = "va";

    public synchronized void print(String first, String second) throws Exception{
        this.first = first;

        Thread.sleep(10000);

        this.second = second;
    }

    public String getFirst() {
        return first;
    }

    public void setFirst(String first) {
        this.first = first;
    }

    public String getSecond() {
        return second;
    }

    public void setSecond(String second) {
        this.second = second;
    }


}

输出:

first : 1 second : va

从上面的程序验证结果来看,stop()确实是不安全的。它的不安全主要是针对于第二点:释放该线程所持有的所有的锁。一般任何进行加锁的代码块,都是为了保护数据的一致性,如果在调用thread.stop()后导致了该线程所持有的所有锁的突然释放,那么被保护数据就有可能呈现不一致性,其他线程在使用这些被破坏的数据时,有可能导致一些很奇怪的应用程序错误。

suspend()和resume()必须要成对出现,否则非常容易发生死锁。
因为suspend方法并不会释放锁,如果使用suspend的目标线程对一个重要的系统资源持有锁,那么没任何线程可以使用这个资源直到要suspend的目标线程被resumed,如果一个线程在resume目标线程之前尝试持有这个重要的系统资源锁再去resume目标线程,这两条线程就相互死锁了,也就冻结线程。

举个例子:

public class Main{
    public static void main(String [] args) throws Exception{
        TestObject testObject = new TestObject();
        Thread t1 = new Thread(){
            public void run(){
                testObject.print();
            }
        };
        t1.setName("A");
        t1.start();
        Thread.sleep(1000);

        Thread t2 = new Thread(){
            public void run(){
                System.out.println("B已启动,但进入不到print方法中");
                testObject.print();
            }
        };
        t2.setName("B");
        t2.start();



    }
}

class TestObject{
    public synchronized void print(){
        if(Thread.currentThread().getName().equals("A")){
            System.out.println("A 线程 独占该资源了");
            Thread.currentThread().suspend();
        }
    }

}

输出:

A 线程 独占该资源了
已启动,但进入不到print方法中
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值