目录
XXXThread.interrupt();
在线程的 run函数中对该线程的中断标记进行判断,自行决定是否终止当前线程。
以及在终止线程之前做一些工作。
interrupt 这个方法并没有强制性地去中断线程任务,只是发送了一个信号给到线程自身,然后让线程自身去决定如何执行。
正因为 interrupt 的灵活性会比较高,所以在 JDK 的线程池中,关于关闭部分的实现也是采用了 interrupt 去实现。
-
- public class InterruptThread2 {
-
- static class TestInterruptedStop implements Runnable {
- @Override
- public void run() {
- synchronized (this) {
- //如果当前线程被中断,这里需要主动退出
- for (int i = 0; i < 100; i++) {
- try {
- Thread.sleep(1000);// sleep 被打断 抛出异常InterruptedException
- // 之后打断标记被清空
- } catch (InterruptedException e) {
- e.printStackTrace();
- System.out.println("sleep遇到了中断,程序即将终止");
- System.out.println("终止前的相关操作...");
- }
- System.out.println("running " + (i+1));
- }
- System.out.println("end");
- }
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
-
- Thread testInterruptedStop = new Thread(new TestInterruptedStop());
- testInterruptedStop.start();
-
- Thread.sleep(2000);
- testInterruptedStop.interrupt();
- Thread.sleep(1000);
- System.out.println("testInterruptedStop is interrupted:" + testInterruptedStop.isInterrupted());
-
- }
-
- }
-
- public class InterruptThread3 {
-
- static class TestInterruptedStop implements Runnable {
- @Override
- public void run() {
- synchronized (this) {
- int i = 1;
- while(!Thread.currentThread().isInterrupted()){
- System.out.println("running " + (i++));
- }
- if(Thread.currentThread().isInterrupted()){// 如果当前线程是打断状态
- System.out.println("遇到了中断,程序即将终止");
- System.out.println("执行终止前的相关操作...");
- }
- System.out.println("end");
- }
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
- Thread testInterruptedStop = new Thread(new TestInterruptedStop());
- testInterruptedStop.start();
-
- Thread.sleep(2000);
- testInterruptedStop.interrupt();
- Thread.sleep(1000);
- System.out.println("testInterruptedStop is interrupted:" + testInterruptedStop.isInterrupted());
-
- }
-
- }
stop 方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁,其它线程将永远无法获取锁
目的仅是停止一个线程,但这种做法会让整个程序都停止
如果被打断线程正处于 sleep、wait、join这三种状态,则会导致被打断的线程抛出 InterruptedException,并清除打断标记,也就是置为 false。
- @Slf4j(topic = "c.TestTwoPhaseTermination")
- public class TestTwoPhaseTermination {
- public static void main(String[] args) throws InterruptedException {
- TPTInterrupt t = new TPTInterrupt();
- t.start();
-
- Thread.sleep(3500);
- log.debug("stop");
- t.stop();
- }
- }
- @Slf4j(topic = "c.TPTInterrupt")
- class TPTInterrupt {
- private Thread thread;
-
- public void start(){
- thread = new Thread(() -> {
- while(true) {
- Thread current = Thread.currentThread();
- if(current.isInterrupted()) {
- log.debug("料理后事");
- break;
- }
- try {
- Thread.sleep(1000);
- log.debug("将结果保存");
- } catch (InterruptedException e) {
- current.interrupt();// 打断标记被清空,需要重新打断设置打断标记为 true
- }
-
- }
- },"监控线程");
- thread.start();
- }
-
- public void stop() {
- thread.interrupt();
- }
- }
sleep 的睡眠被打断会抛出异常,情况打断标记,因此在 catch 块中,需要重新设置打断标记。
