1.7 JAVA多线程编程——停止线程

来源:互联网 发布:mysql int字段累加 编辑:程序博客网 时间:2024/05/17 04:50

1.7 停止线程

首先Thread.stop()方法可以停止一个线程,但是它不安全,而且也是被废弃的,不要去使用它。
大多数停止一个线程的操作是使用Thread.interrupt()方法,该方法不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程的停止。
Java中有以下3种方法可以终止正在运行的线程:
1)使用退出标志,使线程正常退出,即run()方法完成后线程终止。
2)使用stop()方法强行终止线程,但是不推荐使用这个方法,因为stop和suspend及resume一样,都是作废的方法,结果不可预测。
3)使用interrupt()方法中断线程。

1.7.1 interrupt()方法停止线程

调用interrupt()方法仅仅是在当前线程中打了一个停止的标记,并不是真的停止线程。这个比较简单,在run()方法中写个for循环然后在main方法中调用一下类对象的interrupt()方法看看for循环有没有停止就比较直观了。

1.7.2 判断线程的停止状态

这里有两个方法:(1) interrupted() (2)isInterrupted()
两者声明分别为:1.public static boolean interrupted(). 2.public boolean isInterrupted()
其中interrupted()方法是测试当前线程是否已经是中断状态,执行后具有将状态标志清除为false的功能。
isInterrupted()方法是测试线程Thread对象是否已经是中断状态,但不清除状态标志。

具体比较可以看以下代码:

public class Thread_172 {public static void main(String[] args) {    Thread.currentThread().interrupt();    System.out.println("是否停止了1? ==》"+Thread.interrupted());    System.out.println("是否停止了2? ==》"+Thread.interrupted());    System.out.println("====end====");}

}

输出为:
是否停止了1? ==》true
是否停止了2? ==》false
====end====

public class Thread_172_2 {    static class MyThread extends Thread{        public  void run(){            super.run();            for(int i=0;i<900000;i++){                System.out.println("i="+(i+1));            }        }    }public static void main(String[] args) {    try{        MyThread thread = new MyThread();        thread.start();        Thread.sleep(1000);        thread.interrupt();        System.out.println("--------是否停止1?==》 "+thread.isInterrupted());        System.out.println("--------是否停止2?==》 "+thread.isInterrupted());    }catch(InterruptedException e){        System.out.println("main catch");        e.printStackTrace();    }    System.out.println("~~end~~");     }    }i=163187i=163188--------是否停止1?==》 true--------是否停止2?==》 true~~end~~i=163189i=163190i=163191

1.7.3(4) 用异常法停止线程以及在sleep()时停止线程

如果在run()方法中加入if(this.interrupted()){
throw new InterruptedException();
}
然后用try catch包裹住,就相当于用异常法停止了线程,这也是比较常用的方法,也就是避免了for循环后面的语句被运行,在遇到抛出异常后直接进入catch语句块。

来看个代码

public class Thread_174_2 {static class MyThread extends  Thread {    public void run(){        super.run();        try{            for(int i=0;i<10000;i++){                System.out.println("i="+(i+1));            }            System.out.println("run begin");            Thread.sleep(20000);            System.out.println("run end");        }catch (InterruptedException e){            System.out.println("先停止,再遇到了sleep!进入catch!"+this.isInterrupted());            e.printStackTrace();        }    }}public static void main(String[] args) {    MyThread thread = new MyThread();    thread.start();    thread.interrupt();    System.out.println("-------end!");}}输出如下:i=9997i=9998i=9999i=10000run begin先停止,再遇到了sleep!进入catch!falsejava.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at Thread_174_2$MyThread.run(Thread_174_2.java:14)


for循环后的几句没有被运行。

再来看看先sleep再打断

public class Thread_174 {static class MyThread extends  Thread {    public void run(){        try{            System.out.println("run begin");            Thread.sleep(20000);            System.out.println("run end");        }catch (InterruptedException e){            System.out.println("在沉睡中被停止!进入catch!"+this.isInterrupted());            e.printStackTrace();        }    }}public static void main(String[] args) {    try {        MyThread thread = new MyThread();        thread.start();        Thread.sleep(200);        thread.interrupt();    } catch (InterruptedException e) {        System.out.println("main catch");        e.printStackTrace();    }    System.out.println("end!");}

}

输出如下:
run begin
end!
在沉睡中被停止!进入catch!false
Disconnected from the target VM, address: ‘127.0.0.1:61778’, transport: ‘socket’
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at Thread_174$MyThread.run(Thread_174.java:9)

即当我们调用了sleep()方法后,又对其进行中断,那么会抛出异常进入catch语句,并且清除停止状态值。