Java中的线程中断
时间:2020-01-09 10:35:07 来源:igfitidea点击:
线程中断表示线程应停止执行当前正在执行的操作,然后终止或者执行其他操作。线程被中断后的工作由我们自己决定,但是约定是线程一旦中断应终止。
Java中的线程中断如何工作
在Java Thread类中,有一个方法interrupt()中断调用线程。线程中断后,其中断状态将设置为true,然后根据线程当前是否被阻塞而进行后续活动
- 如果在调用Object类的wait(),wait(long)或者wait(long,int)方法或者join(),join(long),join(long,int)方法时阻塞了此线程,sleep(long)或者sleep(long,int)此类的方法,则其中断状态将被清除(再次设置为false),并且将收到InterruptedException。
- 如果此线程在InterruptibleChannel上的I / O操作中被阻止,则该通道将被关闭,该线程的中断状态将被设置,并且该线程将收到ClosedByInterruptException。
- 如果此线程在选择器中被阻塞,则该线程的中断状态将被设置,并且它将立即从选择操作中返回,可能具有非零值,就像调用选择器的唤醒方法一样。
- 如果未阻塞的线程被中断,则将设置该线程的中断状态。
与Java Thread类中的线程中断有关的方法
除了上面已经讨论的方法interrupt()之外,java.lang.Thread类中还有两个与线程中断interrupted()和isInterrupted()相关的方法。
- void interrupt()–中断此线程。
- static boolean interrupted()–检查当前线程是否已被中断。同时清除线程的中断状态。
- boolean isInterrupted()–测试此线程是否已被中断。此方法不会以任何方式更改线程的中断状态。
线程中断的例子
Java中的线程中断通常用于终止阻塞线程。因此,我们可以选择在中断睡眠或者等待线程后仅返回。
public class InterruptDemo implements Runnable { @Override public void run() { for(int i = 0; i < 5; i++){ System.out.println("Value - " + i); try { Thread.sleep(500); } catch (InterruptedException e) { System.out.println("Thread " + Thread.currentThread().getName() + " interrupted, reason " + e.getMessage()); System.out.println("Interrupted status- " + Thread.currentThread().isInterrupted()); return; } } } public static void main(String[] args) { Thread t = new Thread(new InterruptDemo()); t.start(); t.interrupt(); System.out.println("In main method - Interrupted status " + t.isInterrupted()); } }
输出:
In main method - Interrupted status true Value - 0 Thread Thread-0 interrupted, reason sleep interrupted Interrupted status- false
在线程的run方法中,有一个循环来打印从1到5的数字,每次显示数字后,都会在线程上调用sleep方法。同时,也会调用线程的中断方法,以中断被阻塞的线程。我们还可以看到在调用interrupt()方法之后,中断状态为true,然后清除了中断状态(设置为false)。
包装并重新抛出InterruptedException
我们可以选择包装InterruptedException并将其重新抛出,而不是像前面的示例中那样返回。
public class InterruptDemo implements Runnable { @Override public void run() { for(int i = 0; i < 5; i++){ System.out.println("Value - " + i); try { Thread.sleep(500); } catch (InterruptedException e) { System.out.println("Thread " + Thread.currentThread().getName() + " interrupted, reason " + e.getMessage()); System.out.println("Interrupted status- " + Thread.currentThread().isInterrupted()); throw new RuntimeException("Thread interrupted", e); } } } public static void main(String[] args) { Thread t = new Thread(new InterruptDemo()); t.start(); t.interrupt(); System.out.println("In main method - Interrupted status " + t.isInterrupted()); } }
输出:
In main method - Interrupted status true Value - 0 Thread Thread-0 interrupted, reason sleep interrupted Interrupted status- false Exception in thread "Thread-0" java.lang.RuntimeException: Thread interrupted at com.theitroad.InterruptDemo.run(InterruptDemo.java:14) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.theitroad.InterruptDemo.run(InterruptDemo.java:10) ... 1 more
中断非阻塞线程
如果中断未阻塞的线程,则仅线程的中断状态会更改。使用isInterrupted()方法,我们可以检查线程的中断状态,并选择在该条件下执行一些逻辑。
public class InterruptDemo implements Runnable { @Override public void run() { for(int i = 0; i < 5; i++){ System.out.println("Value - " + i); if(Thread.currentThread().isInterrupted()){ System.out.println("Interrupted status- " + Thread.currentThread().isInterrupted()); } } } public static void main(String[] args) { Thread t = new Thread(new InterruptDemo()); t.start(); t.interrupt(); System.out.println("In main method - Interrupted status " + t.isInterrupted()); } }
输出:
In main method - Interrupted status true Value - 0 Interrupted status- true Value - 1 Interrupted status- true Value - 2 Interrupted status- true Value - 3 Interrupted status- true Value - 4 Interrupted status- true
如我们所见,在这种情况下,中断状态保持为true,不会像被中断的阻塞线程一样清除为false。