作者:淡水鱼yw灬s | 来源:互联网 | 2023-10-12 08:38
写在前面:之前在一篇博客中介绍了线程中断的相关内容(http:blog.csdn.netmay_3articledetails79393281),在Java锁的实现中
写在前面:
之前在一篇博客中介绍了线程中断的相关内容(http://blog.csdn.net/may_3/article/details/79393281),在Java锁的实现中也有使用中断的地方,所以想用一篇博客再好好总结一下线程的中断。
中断:
中断是线程的一个标识位属性,表示运行中的线程是否对其他线程进行了中断操作。其他线程是通过interrupt方法来中断线程。
比如:当一个线程A调用sleep方法,进入睡眠状态,等待1s,等待线程B完成,但如果其他线程B提前完成,想要线程A提前结束睡眠状态,就会调用该线程的interrupt方法,中断线程A。
(1) 对于非阻塞的线程,调用Interrupt方法只会改变线程的中断标识位,即Thread.isInterrupted()会返回true
(2) 对于可从阻塞状态中取消的线程(比如:线程调用了Thread.sleep/Thread.join/Object.wait等)调用Interrupt方法,程序会抛出一个InterruptedException异常,同时将中断状态置回为true(调用Thread.Interrupted可以对中断状态复位)。
IsInterrupted方法会检查线程是否中断,并返回一个boolean,且不会清楚中断标志位。是对象的方法,调用方式Thread.currentThread.IsInterrupted().
Interrupted方法同样会返回中断标志位,并重置标志位。
(1)中断非阻塞方法
中断非阻塞方法,只是更改了标识位,并不影响程序的运行。
package test3;public class InterruptDemo {public static void main(String[] args) {Thread thread1 = new Thread(new ThreadDemo1(), "线程1");thread1.start();try {Thread.sleep(2000);// 主线程睡眠1秒} catch (InterruptedException e) {e.printStackTrace();}thread1.interrupt();}}class ThreadDemo1 implements Runnable {@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()) {System.out.println(Thread.currentThread().getName());}if (Thread.currentThread().isInterrupted()) {System.out.println("被中断");}}}
(2)中断阻塞方法
当线程调用了wait、sleep、join方法时,线程会进入阻塞状态,对线程进行中断,会提前结束阻塞状态(并不会改变中断的状态),并且抛出一个InterruptedException。
代码:
package test3;public class InterruptDemo {public static void main(String[] args) {Thread thread1 = new Thread(new ThreadDemo1(), "线程1");thread1.start();try {Thread.sleep(1000);// 主线程睡眠1秒} catch (InterruptedException e) {e.printStackTrace();}thread1.interrupt();}}class ThreadDemo1 implements Runnable {@Overridepublic void run() {try {Thread.sleep(2000);// 子线程睡眠1秒} catch (InterruptedException e) {e.printStackTrace();System.out.println("子线程的中断状态为" + Thread.currentThread().isInterrupted());}}}
我们来分析一下代码的实现过程:
(1)首先子线程启动,主线程睡眠1秒,这时子线程一直处于睡眠即阻塞状态。
(2)当主线程醒来,对睡眠中的子线程中断,子线程停止阻塞状态,并会抛出一个InterruptedException异常。此时打印当前线程的中断状态为false。注:说明中断阻塞状态的线程不会改变中断状态。
(3)后面如果还有代码,仍然会正常执行。
(3)不可中断线程。
当线程被synchronized修饰或者处于reentrantLock.lock()获取锁的过程中,则线程不可以被中断。但我们可以使用超时tryLock方法来对线程中断,即ReentrantLock.tryLock(longtimeout, TimeUnit unit),中断后,会抛出一个InterruptedException异常。