java thread stop中止线程 不抛出异常 没有异常信息

前言

Thread的实例方法stop()用来中止线程,它是真正的中止线程,与之相对应的interrupt()是一种提示性中止,因为没有留出机会让程序员处理资源,stop()会带来状态一致性问题,所以已不推荐使用,不过这里是为了探究为什么不推荐使用,所以研究。

中止线程

public class MyThread extends Thread {


    @Override
    public void run() {
        System.out.println("begin");
        try {
            this.stop();
        } catch (ThreadDeath e) {
            System.out.println("进入catch块了");
            e.printStackTrace();
        }
        System.out.println("end");
    }
}

public class StopRun {
    public static void main(String[] args) throws InterruptedException {

        MyThread myThread = new MyThread();
        myThread.start();


    }
}

输出结果

java.lang.ThreadDeath
	at java.lang.Thread.stop(Thread.java:850)
	at extthread.MyThread.run(MyThread.java:13)
begin
进入catch块了
end

根据java api所述,

无论该线程在做些什么,它所代表的线程都被迫异常停止,并抛出一个新创建的 ThreadDeath 对象,作为异常。

通过输出可以看到的确抛出了ThreadDeath,以上示例是参考《Java多线程编程核心技术》一书所写,在实践中我稍微改了一下却发现,没有任何异常信息。

public class MyThread extends Thread {


    @Override
    public void run() {
        System.out.println("begin");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("end");
    }
}
public class StopRun {
    public static void main(String[] args) throws InterruptedException {

        MyThread myThread = new MyThread();
        myThread.start();
		//让myThread得到机会运行
        Thread.sleep(200);
        myThread.stop();

    }
}

此种写法,控制台什么也没输出!当时我就纳闷了?不应该呀,按照api,stop()方法肯定会抛出ThreadDeath。后来一想,抛出的异常应该在目标线程抛出,而非执行线程抛出,在本例中myThread是目标线程,主线程是执行线程。果断将MyThread的run()方法,try catch,经此一改,果然出现异常信息了

 @Override
    public void run() {
        try {
            System.out.println("begin");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }catch (ThreadDeath e){
            e.printStackTrace();
        }
        System.out.println("end");
    }

输出结果

begin
java.lang.ThreadDeath
	at java.lang.Thread.stop(Thread.java:850)
	at test.StopRun.main(StopRun.java:14)
end

ThreadDeath

顺便提一下ThreadDeath,按照api规定,stop()时会抛出ThreadDeath,ThreadDeath是继承自Error,而非Exception子类,通常情况下,是不需要catch的,上边的例子只是为了演示,所以catch。所以在catch时,应该catch(Error)或者catch(ThreadDeath),而不应该catch(Exception),catch(Exception)也不会打印异常信息。
在这里插入图片描述

状态一致性问题

stop()属于暴力强制中止线程,会带来状态一致性问题。

public class SynchronizedObject {

    private String userName = "a";
    private String password = "aa";

    public synchronized  void printString(String userName, String password){

        try {
            this.userName = userName;
            Thread.sleep(100000);
            this.password = password;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
public class SynchronizedThread extends Thread {

    private SynchronizedObject object;

    public SynchronizedThread(SynchronizedObject object) {
        this.object = object;
    }

    @Override
    public void run() {
        object.printString("b","bbb");
    }
}
 public static void main(String[] args) throws InterruptedException {
        SynchronizedObject object = new SynchronizedObject();
        SynchronizedThread t = new SynchronizedThread(object);
        t.start();
        Thread.sleep(500);
        t.stop();
        System.out.println(object.getUserName()+"-"+object.getPassword());

    }

输出结果,可以看到因为stop()的强制中止,没有给程序员预留善后空间,导致状态不一致;理论上,使用stop()的地方都应该使用interrupt()代替;

b-aa

参考

java多线程编程核心技术 高洪岩著

发布了336 篇原创文章 · 获赞 369 · 访问量 193万+

猜你喜欢

转载自blog.csdn.net/wangjun5159/article/details/103711865