通常我们会有这样的需求,即停止一个线程。在java的api中有stop、suspend等方法可以达到目的,但由于这些方法在使用上存在不安全性,会带来不好的副作用,不建议被使用。
在本文中,将讨论中断在java中的理解和使用。
借助《java并发编程的艺术》艺术中的定义:中断可以理解为线程的一个标识位属性,他表示一个运行中的线程是否被其他线程进行了中断操作。中断好比其他线程对该线程打了个招呼,其他线程通过调用该线程的interrupt方法对其进行中断操作!然后,线程通过检查自身是否被中断来进行响应,线程通过方法isINterrupt来进行判断是否被中断,同时,线程也可以使用Thread的静态static方法对其中断标识位进行复位。
需要注意的是,如果该线程已经处于终结状态,即使该线程被中断过,在调用该线程对象的isInterrupt是依旧会放回false
中断在java中主要有3个方法,interrupt(),isInterrupted()和interrupted()。
- interrupt(),在一个线程中调用另一个线程的interrupt()方法,即会向那个线程发出信号——线程中断状态已被设置。至于那个线程何去何从,由具体的代码实现决定。
- isInterrupted(),用来判断当前线程的中断状态(true or false)。
- interrupted()是个Thread的static方法,用来恢复中断状态,名字起得额?。
接下来,看看具体在代码中如何使用。
interrupt()不能中断在运行中的线程,它只能改变中断状态而已。
public class InterruptionInJava implements Runnable{public static void main(String[] args) throws InterruptedException {Thread testThread = new Thread(new InterruptionInJava(),"InterruptionInJava");//start threadtestThread.start();Thread.sleep(1000);//interrupt threadtestThread.interrupt();System.out.println("main end");}@Overridepublic void run() {while(true){if(Thread.currentThread().isInterrupted()){System.out.println("Yes,I am interruted,but I am still running");}else{System.out.println("not yet interrupted");}}}
}
结果显示,被中断后,仍旧运行,不停打印Yes,I am interruted,but I am still running
那么,如何正确中断?
既然是只能修改中断状态,那么我们应该针对中断状态做些什么。
public void run() {while(true){if(Thread.currentThread().isInterrupted()){System.out.println("Yes,I am interruted,but I am still running");return;}else{System.out.println("not yet interrupted");}}}
修改代码,在状态判断中添加一个return。这也解释了中断仅作为一个标识位的意义,中断后的线程的执行逻辑,还是依赖于代码!
|
通过上述讨论,我们其实也就找到了一种思路,如何安全的终止线程?
这里只是简略的提一下,这其实受到了中断标识位的启发,我们设置一个boolean变量,然后run中的while循环可以让次boolean变量作为判断依据,我们通过控制boolean的代码逻辑,实现run方法的安全结束!