首页 > 其他分享 >Thread 之 interrupt、isInterrupted、interrupted 方法

Thread 之 interrupt、isInterrupted、interrupted 方法

时间:2024-01-10 17:35:07浏览次数:35  
标签:标记 interrupted t1 isInterrupted 线程 打断 interrupt

interrupt(): 打断 sleep、wait、join 的线程会抛出 InterruptedException 异常并清除打断标记,如果打断正在运行的线程、park 的线程则会重新设置打断标记
isInterrupted(): 不会清除打断标记
interrupted(): 会清除打断标记

一、调用 interrupt() 方法中断正在运行的线程

@Slf4j
public class InterruptDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (true) {

            }
        });
        t1.start();

        // 先让 t1 线程运行
        TimeUnit.SECONDS.sleep(1);
        // isInterrupted() 可以获取到线程的打断标记,如果线程被打断,则打断标记为 true,并且该方法不会清除打断标记
        log.info("before interrupt status >>> {}", t1.isInterrupted());
        // 打断正在运行的线程/park 状态的线程会重新设置打断标记,打断 sleep、join、wait 状态的线程会抛出 InterruptedException 异常,并且会清除打断标记
        t1.interrupt();
        log.info("after interrupt status >>> {}", t1.isInterrupted());
    }
}

中断正在运行的线程时,线程的中断状态变成 true,线程正常运行,并不会停止下来

调用 interrupt() 方法中断处于 sleep、wait、join 状态的线程

@Slf4j
public class InterruptDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                // t1 线程休眠 1000s
                TimeUnit.SECONDS.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                log.info("{} 线程被打断了", Thread.currentThread().getName());
            }
        }, "t1");

        t1.start();

        // 主线程休眠 2s,让 t1 线程有足够的时间进入 sleep 状态
        TimeUnit.SECONDS.sleep(2);
        log.info("before interrupt status >>> {}", t1.isInterrupted());
        t1.interrupt();
        // 主线程休眠 2s,让 t1 线程有足够的时间进行 interrupt 操作
        TimeUnit.SECONDS.sleep(2);
        log.info("after interrupt status >>> {}", t1.isInterrupted());
    }
}

中断处于 sleep、join、wait 状态的线程会抛出异常,并且会将中断状态重置为 false

 中断时线程的状态  中断后线程的中断标记 中断后线程运行情况 
 正常运行的线程  false -> true  线程正常运行
 sleep、wait、join 状态的线程  false -> true -> false  线程抛出异常,中止运行

然后再看一下 isInterrupted 和 interrupted 的区别

先看一下 isInterrupted() 方法源码

public boolean isInterrupted() {
	// ClearInterrupted 参数的含义是否清除打断标记 
	// false 代表不清除,打断之后 false -> true
	// true 代表清除,打断之后会重置打断标记 false -> true -> false
	return isInterrupted(false);
}
private native boolean isInterrupted(boolean ClearInterrupted);

接着再看一下 interrupted() 方法源码

public static boolean interrupted() {
	return currentThread().isInterrupted(true);
}
private native boolean isInterrupted(boolean ClearInterrupted);

从上面的源码中可以看出 isInterrupted() 方法和 interrupted() 方法实际上底层都是调用 private native boolean isInterrupted(boolean ClearInterrupted) 方法,唯一的区别就是传递的参数,一个是 false,一个是 true,也就是一个不会清除打断标记,另外一个会清除打断标记

线程调用 interrupt() 方法并不会真正中断线程,而是让线程具有响应中断的能力,如果你可以在 main 线程中随意的去停止 t1 线程,而 t1 线程却毫无察觉,这不是一件很可怕的事情吗,真正中断的操作应该由 t1 线程去决定,而不是 main 线程,常用的做法是在 t1 线程中根据打断标记去执行不同的逻辑

 

 

 

标签:标记,interrupted,t1,isInterrupted,线程,打断,interrupt
From: https://www.cnblogs.com/xiaomaomao/p/17231206.html

相关文章

  • System Suspend and Device Interrupts 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/power/suspend-and-interrupts.html系统挂起和设备中断版权©2014IntelCorp.作者:[email protected]挂起和恢复设备中断在系统挂起后(即在所有设备的->prepare、->suspend和->suspend_late回调已经执行......
  • Thread常见方法:interrupt 方法详解
    打断sleep,wait,join的线程这几个方法都会让线程进入阻塞状态打断sleep的线程,会清空打断状态,以sleep为例privatestaticvoidtest1()throwsInterruptedException{Threadt1=newThread(()->{sleep(1);},"t1");t1.start();sleep(0.5);t1.interrupt();l......
  • 线程中断方法详解interrupt
    线程中断方法详解interrupt由于stop中断线程方法过于暴力,就像是突然你正在开发,突然停电一样于是衍生出中断方法interrupt简介线程中断并不会使线程立即退出,而是给线程发送一个通知,告知目标线程,有人希望你退出了!至于目标线程接收到通知之后如何处理,则完全由目标线程自己决定Thread提......
  • Go - Using channels to receive interrupts in a program
    WithintheKubernetesdeploymentenvironment,applicationswillactuallybesent theSIGTERMsignalfirstifithasbeendecidedthepodholdingtheapplicationneeds tobestopped.Theapplicationmaychoosetorespondtosaidsignalornot.Ifthe appli......
  • Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: int
    执行mybatis的mapper方法时,报错了这个错。通过网上查找,发现了是JDK版本和oracle版本不一致导致的。(我直接从JDK1.8换成JDK11就可以了) 以下内容转自:FailedtoobtainJDBCConnection;nestedexceptionisjava.sql.SQLException:oracle.jdbc.OracleDriver_小沈同学_的博客-CS......
  • java isInterrupted
    Java中的isInterrupted方法在Java中,线程是一种并发执行的代码单元,它允许我们同时执行多个任务。然而,在多线程编程中,我们经常需要控制和管理线程的行为。Java提供了许多方法来帮助我们实现这一目标之一就是isInterrupted方法。什么是isInterrupted方法?isInterrupted方法是Java中T......
  • Java并发编程 interrupt()方法
    interrupt()用法打断正常运行的线程interrrupt()方法可以用来打断正在运行的线程,也可以打断sleep()、wait()、join()情况下的线程,但是这些情况下被打断线程的打断标记不同。importlombok.extern.slf4j.Slf4j;importjava.util.concurrent.TimeUnit;@Slf4jpublicclassIn......
  • interrupt()
    在Java中,interrupt()方法可以用来中断线程。当一个线程调用interrupt()方法时,该线程的中断标志位会被设置为true,表示该线程被中断了。如果线程正在执行wait()、sleep()或join()方法时,会抛出InterruptedException异常,并且中断标志位会被清除,即变为false。如果线程没有在执行这些方......
  • Java并发(九)----线程join、interrupt
    1、join方法详解1.1为什么需要join?下面的代码执行,打印r是什么?staticintr=0;publicstaticvoidmain(String[]args)throwsInterruptedException{  test1();}privatestaticvoidtest1()throwsInterruptedException{  log.debug("开始");  T......
  • Query execution was interrupted, maximum statement execution time exceeded
    数据库版本:MySQL5.7.16报错信息:ERROR3024(HY000):Queryexecutionwasinterrupted,maximumstatementexecutiontimeexceeded检查bug库,发现同样问题:https://bugs.mysql.com/bug.php?id=83339原因是max_execution_time设置过小导致。复现:将max_execution_time设置成......