[25]stop方法被抛弃的原因和代替方法

在JAVA API中写着:

stop()方法无论线程在什么状态下所代表的线程都将被强制停止

class ThreadStop implements Runnable{
    private int num;
    @override
    public void run(){
        while(count<10){
            try{
                Thread.sleep(300);
            }catch(InterruputExpcetion e){
                e.printStackTrace();
            }
        }
    System.out.println(Thread.currentThread().getName()+" : stop");
    }
}

class Demo{
    public static void main(String[] args){
        ThreadStop stop=new ThreadStop();
        Thread t1=new Thread(stop);

        t1.start();

        try{
            Thread.sleep(2000);
        }catch(InterruputExpcetion e){
            e.printStackTrace();
        }
        t1.stop;

        System.out.println(Thread.currentThread().getName+" : stop");
    }
}

运行结果:

Thread-0 : 0
Thread-0 : 1
Thread-0 : 2
Thread-0 : 3
Thread-0 : 4
Thread-0 : 5
Thread-0 : 6
main : stop

运行结果中,缺少了Thread-0 : stop。因为线程已经被强制停止了。后续的内容也不会再执行,这是stop()的作用也是缺点。如果在后面写的不是输出语句,而是释放资源的内容那么影响就比较的大了

所以,API里面也介绍了这么一段话:

stop 的许多使用都应由只修改某些变量以指示目标线程应该停止运行的代码来取代。目标线程应定期检查该变量,并且如果该变量指示它要停止运行,则从其运行方法依次返回。如果目标线程等待很长时间(例如基于一个条件变量),则应使用 interrupt 方法来中断该等待。

简而言之:

停止线程的代码不用stop()而是定义一个变量来取代,并且需要定期检查(while条件),如果目标线程需要等待很长时间(如果sleep(300)变成了wait(),那么就是长时间的等待了),则应使用interruput来中断。

interrupt():API中介绍是在用到sleep(),wait(),join()无参或有参方法时受阻,那么清除其中断状态,并返回一个异常。

所以改进如下

class ThreadStop implements Runnable{
    private int num;
    private boolean flag;//标记,也就是用来替代stop()的变量
    /*因为需要用到wait()所以加上synchronized也可以使用同步代码块*/
    @override
    public synchronized void run(){
        while(!flag){
           if(num==5){
             try{
                this.wait();//等待时间过长
             }catch(InterruputExpcetion e){
/*因为目的是停止线程,wait()被中断了,所以执行异常内容,因为要停止,那么要先使判断条件为false*/
                changeFlag();
                e.printStackTrace();
                }    
            }
        }
    System.out.println(Thread.currentThread().getName()+" : stop");
    }
    /*如果程序需要停止,改变flag的值,得到stop()的作用*/
    public void changeFlag(){
        this.flag=!flag;
    }
}

class Demo{
    public static void main(String[] args){
        ThreadStop stop=new ThreadStop();
        Thread t1=new Thread(stop);

        t1.start();

        try{
            Thread.sleep(2000);
        }catch(InterruputExpcetion e){
            e.printStackTrace();
        }
        t1.interrupt();//因为t1线程wait()受阻,等待时间过长,所以用interrupt()来中断

        System.out.println(Thread.currentThread().getName+" : stop");
    }
}

输出结果:

Thread-0 : 0
Thread-0 : 1
Thread-0 : 2
Thread-0 : 3
Thread-0 : 4
main : stop
java.lang.InterruptedException
Thread-0 : stop
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Unknown Source)
    at com.stop.ThreadStop.run(ThreadStop.java:15)
    at java.lang.Thread.run(Unknown Source)

其中 java.lang.InterruptedException为interrupt()返回的异常。

而下面一大串的异常,是因为wait()被中断,所以抛出的异常。

并且也可以看到之前缺少的Thread-0 : stop

 

所以总结一下:

stop()被抛弃的原因
1.虽然停止了线程,但是线程并未执行完,会导致没有释放资源

解决方案

1.将interrupt()用来代替stop()
2.interrupt()是清除中断状态的,并不是终止线程
所以如果只是将stop替换成interrupt的话,那程序会继续执行,并没有终止
3.所以用一个标记来结束循环条件,并写一个修改标记的放在catch中

你可能感兴趣的:([25]stop方法被抛弃的原因和代替方法)