中断机制 Java语言提供一种机制来试图“终止”一些特殊的线程,比如一下空转的线程一直消耗系统资源,可以使用中断的方式来停止这一类的线程,这就是Java中断机制。
1、中断注意的地方 1、Java中线程间是协作式,而非抢占式 . 调用一个线程的interrupt() 方法中断一个线程,并不是强行关闭这个线程,只是跟这个线程打个招呼,将线程的中断标志位置为true,线程是否中断,由线程本身决定。
2、isInterrupted() 判定当前线程是否处于中断状态。
3、静态方法 interrupted() 判定当前线程是否处于中断状态,同时中断标志位改为 false。
4、如果方法里如果抛出中断异常 InterruptedException,则线程的中断标志位会被复位成false ,如果确实是需要中断线程,要求我们自己在catch语句块里再次调用interrupt()。
5、Java 中所有的阻塞方法都会抛出 InterruptedException,比如wait(), join(),sleep()。
2、Java中断提供的方法 在Java中提供了3个有关中断的方法:
Thread.currentThread().isInterrupted()
判断当前的线程是否被中断
thread.interrupt();
中断一个线程,将中断标志设置成true
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public void interrupt () { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null ) { interrupt0(); b.interrupt(this ); return ; } } interrupt0(); }
Thread.interrupted() 1 2 3 public static boolean interrupted () { return currentThread().isInterrupted(true ); }
判断线程是否被中断,并清除中断标志,改成false;
验证一下就可以了 👇
1 2 3 4 5 6 7 8 public static void main (String[] args) { System.err.println(Thread.currentThread().isInterrupted()); Thread.currentThread().interrupt(); System.err.println(Thread.currentThread().isInterrupted()); boolean interrupted = Thread.interrupted(); System.err.println("interrupted " + interrupted); System.err.println(Thread.currentThread().isInterrupted()); }
3、中断例子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class InterrupterDemo { public static void main (String[] args) throws InterruptedException { Thread thread = new Thread(() -> { while (true && !Thread.currentThread().isInterrupted()){ System.err.println(1 ); System.err.println(Thread.interrupted()); try { Thread.sleep(1000 ); } catch (InterruptedException e) { System.err.println("after sleep " + Thread.currentThread().isInterrupted()); Thread.currentThread().interrupt(); boolean interrupted = Thread.interrupted(); System.err.println("interrupted " + Thread.currentThread().isInterrupted() + "/ " + interrupted); Thread.currentThread().interrupt(); System.err.println("final sleep " + Thread.currentThread().isInterrupted()); break ; } System.err.println(2 ); } }); thread.start(); Thread.sleep(3000 ); thread.interrupt(); } }
注意,中断一场不要【 吞掉 】,要不在程序中相应中断一场,进行相应的逻辑处理,或者将一场继续向上抛,由上层处理。
参考资料 https://dayarch.top/p/java-concurrency-interrupt-mechnism.html