java线程中断,也是一个比较难懂的点,但是面试会经常问到,其实中断就是有2种情况,一种是可阻塞中断(调用wait、sleep,join 方法),一种是不可阻塞中断(争夺锁sychnrozied)。
对于可中断阻塞而言,我们可以通过线程的
isInterrupted() interrupt() interrputed()
三个方法来实现:
- isInterrupted() 判断线程是否中断
- interrupt() 中断线程,给线程中断标志设为true
- interrputed() 测试当前线程是否已经中断并且线程的“中断状态”由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false。这是一个Thread方法,针对的是当前线程,不是调用线程。
/**
* Tests whether the current thread has been interrupted. The
* <i>interrupted status</i> of the thread is cleared by this method. In
* other words, if this method were to be called twice in succession, the
* second call would return false (unless the current thread were
* interrupted again, after the first call had cleared its interrupted
* status and before the second call had examined it).
*
* <p>A thread interruption ignored because a thread was not alive
* at the time of the interrupt will be reflected by this method
* returning false.
*
* @return <code>true</code> if the current thread has been interrupted;
* <code>false</code> otherwise.
* @see #isInterrupted()
* @revised 6.0
*/
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
看看Thread.interrupted方法的具体解释,1 返回的是当前线程的中断标志位状态,2 清除当前线程的中断标志位(如果是true,置为false,是false则不管)。记住是先返回状态,在进行清除,否则就会一直返回false;这样也会有连续调用两次会返回false的情况。
代码示例
public class MyThread extends Thread {
@Override
public void run() {
super.run();
System.out.println("线程标志位" + this.isInterrupted());
System.out.println("执行任务");
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("异常 线程标志位" + this.isInterrupted());
}
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
thread.interrupt();
}
打印结果
执行任务
线程标志位true
异常 线程标志位false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.sjh.interrupt.MyThread.run(MyThread.java:11)
分析:线程启动后,调用线程interrupt 方法,给线程的中断标志位设置为true,但线程sleep时,遇到可中断阻塞后就通过抛出异常来进行中断线程,并且在抛出异常后立即将线程的中断标示位清除,即重新设置为false。同时还要注意interrupt方法只是给线程的标志改变一下,线程是否中断是由线程自己决定的,有可能线程一直都会中断,直到线程执行完,所以说interrupt 中断线程是一种协商机制。
不可中断阻塞线程
这种情况,要么线程执行完进行dead状态,也就不必要中断,要么就是那种线程里面是一个死循环,当我们想要中断这种线程,其实就是让他跳出循环,任务执行完就ok 了,
public volatile boolean flag = false;
public StopThread(String name) {
super(name);
}
@Override
public void run() {
super.run();
while (true){
if (flag){
System.out.println("中断");
break;
}
try {
System.out.println("执行任务");
}catch (Exception e){
e.printStackTrace();
System.out.println("异常");
}
}
}
public static void main(String[] args) {
StopThread stopThread = new StopThread("stopThread");
stopThread.start();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
stopThread.flag = true;
}