Thread.interrupt()的作用是通知线程应该中断了,到底中断还是继续运行,应该由被通知的线程自己处理。当对一个线程,调用 interrupt() 时,

  1. 如果线程处于被阻塞状态(例如处于sleep, wait, join 等状态),那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。仅此而已。然后会将打断标记重置
  2. 如果线程处于正常活动状态,那么会将该线程的中断标志设置为 true,仅此而已。被设置中断标志的线程将继续正常运行,不受影响。

注意点:

  • interrupt是对象方法: 如果被打断线程正在 sleep,wait,join 会导致被打断 的线程抛出 InterruptedException,并清除 打断标 记 ;如果打断的正在运行的线程,则会设置 打断标 记 ;park 的线程被打断,也会设置 打断标记
  • isInterrupted方法是对象方法用于获取当前线程的打断标志的状态
  • interrupted方法是Thread的静态方法,判断当前线程是 否被打断 会清除 打断标记

对于第一种情况

  1. @Slf4j
  2. public class Test2 {
  3. public static void main(String[] args) throws Exception{
  4. Thread t1 = new Thread(()->{
  5. try {
  6. Thread.sleep(5000);
  7. } catch (InterruptedException e) {
  8. e.printStackTrace();
  9. }
  10. }, "t1");
  11. t1.start();
  12. t1.sleep(1000);
  13. t1.interrupt();
  14. log.debug(" 打断状态: {}", t1.isInterrupted());
  15. }
  16. }
  17. 输出
  18. E:\jdk1.8.0_131\jdk1.8.0_131\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.1\lib\idea_rt.jar=53363:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.1\bin" -Dfile.encoding=UTF-8 -classpath E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\charsets.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\deploy.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\dnsns.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\jaccess.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\localedata.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\nashorn.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\sunec.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\ext\zipfs.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\javaws.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\jce.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\jfr.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\jfxswt.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\jsse.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\management-agent.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\plugin.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\resources.jar;E:\jdk1.8.0_131\jdk1.8.0_131\jre\lib\rt.jar;E:\A_lshady\boot_falsework\boot-start\target\classes;E:\Maven\ideamaven\com\dtflys\forest\forest-spring-boot-starter\1.5.14\forest-spring-boot-starter-1.5.14.jar;E:\Maven\ideamaven\com\dtflys\forest\forest-core\1.5.14\forest-core-1.5.14.jar;E:\Maven\ideamaven\com\googlecode\juniversalchardet\juniversalchardet\1.0.3\juniversalchardet-1.0.3.jar;E:\Maven\ideamaven\org\apache\httpcomponents\httpclient\4.5.13\httpclient-4.5.13.jar;E:\Maven\ideamaven\commons-codec\commons-codec\1.15\commons-codec-1.15.jar;E:\Maven\ideamaven\org\apache\httpcomponents\httpclient-cache\4.5.13\httpclient-cache-4.5.13.jar;E:\Maven\ideamaven\org\apache\httpcomponents\httpcore\4.4.14\httpcore-4.4.14.jar;E:\Maven\ideamaven\org\apache\httpcomponents\httpmime\4.5.13\httpmime-4.5.13.jar;E:\Maven\ideamaven\com\squareup\okhttp3\okhttp\3.14.9\okhttp-3.14.9.jar;E:\Maven\ideamaven\com\squareup\okio\okio\1.17.2\okio-1.17.2.jar;E:\Maven\ideamaven\com\google\code\findbugs\jsr305\3.0.1\jsr305-3.0.1.jar;E:\Maven\ideamaven\commons-io\commons-io\2.7\commons-io-2.7.jar;E:\Maven\ideamaven\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;E:\Maven\ideamaven\com\dtflys\forest\forest-spring\1.5.14\forest-spring-1.5.14.jar;E:\Maven\ideamaven\com\google\protobuf\protobuf-java\3.14.0\protobuf-java-3.14.0.jar;E:\Maven\ideamaven\com\oracle\ojdbc6\11.2.0.3\ojdbc6-11.2.0.3.jar;E:\Maven\ideamaven\com\alibaba\druid-spring-boot-starter\1.2.8\druid-spring-boot-starter-1.2.8.jar;E:\Maven\ideamaven\com\alibaba\druid\1.2.8\druid-1.2.8.jar;E:\Maven\ideamaven\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;E:\Maven\ideamaven\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;E:\Maven\ideamaven\org\springframework\boot\spring-boot-autoconfigure\2.5.6\spring-boot-autoconfigure-2.5.6.jar;E:\Maven\ideamaven\org\springframework\boot\spring-boot\2.5.6\spring-boot-2.5.6.jar;E:\Maven\ideamaven\com\baomidou\mybatis-plus-boot-starter\3.4.3.4\mybatis-plus-boot-starter-3.4.3.4.jar;E:\Maven\ideamaven\com\baomidou\mybatis-plus\3.4.3.4\mybatis-plus-3.4.3.4.jar;E:\Maven\ideamaven\com\baomidou\mybatis-plus-extension\3.4.3.4\mybatis-plus-extension-3.4.3.4.jar;E:\Maven\ideamaven\com\baomidou\mybatis-plus-core\3.4.3.4\mybatis-plus-core-3.4.3.4.jar;E:\Maven\ideamaven\com\baomidou\mybatis-plus-annotation\3.4.3.4\mybatis-plus-annotation-3.4.3.4.jar;E:\Maven\ideamaven\org\mybatis\mybatis\3.5.7\mybatis-3.5.7.jar;E:\Maven\ideamaven\org\mybatis\mybatis-spring\2.0.6\mybatis-spring-2.0.6.jar;E:\Maven\ideamaven\org\springframework\boot\spring-boot-starter-jdbc\2.5.6\spring-boot-starter-jdbc-2.5.6.jar;E:\Maven\ideamaven\com\zaxxer\HikariCP\4.0.3\HikariCP-4.0.3.jar;E:\Maven\ideamaven\org\springframework\spring-jdbc\5.3.12\spring-jdbc-5.3.12.jar;E:\Maven\ideamaven\com\github\pagehelper\pagehelper-spring-boot-starter\1.2.5\pagehelper-spring-boot-starter-1.2.5.jar;E:\Maven\ideamaven\org\springframework\boot\spring-boot-starter\2.5.6\spring-boot-starter-2.5.6.jar;E:\Maven\ideamaven\org\springframework\boot\spring-boot-starter-logging\2.5.6\spring-boot-starter-logging-2.5.6.jar;E:\Maven\ideamaven\ch\qos\logback\logback-classic\1.2.6\logback-classic-1.2.6.jar;E:\Maven\ideamaven\ch\qos\logback\logback-core\1.2.6\logback-core-1.2.6.jar;E:\Maven\ideamaven\org\apache\logging\log4j\log4j-to-slf4j\2.14.1\log4j-to-slf4j-2.14.1.jar;E:\Maven\ideamaven\org\apache\logging\log4j\log4j-api\2.14.1\log4j-api-2.14.1.jar;E:\Maven\ideamaven\org\slf4j\jul-to-slf4j\1.7.32\jul-to-slf4j-1.7.32.jar;E:\Maven\ideamaven\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;E:\Maven\ideamaven\org\yaml\snakeyaml\1.28\snakeyaml-1.28.jar;E:\Maven\ideamaven\org\mybatis\spring\boot\mybatis-spring-boot-starter\1.3.2\mybatis-spring-boot-starter-1.3.2.jar;E:\Maven\ideamaven\org\mybatis\spring\boot\mybatis-spring-boot-autoconfigure\1.3.2\mybatis-spring-boot-autoconfigure-1.3.2.jar;E:\Maven\ideamaven\com\github\pagehelper\pagehelper-spring-boot-autoconfigure\1.2.5\pagehelper-spring-boot-autoconfigure-1.2.5.jar;E:\Maven\ideamaven\com\github\pagehelper\pagehelper\5.1.4\pagehelper-5.1.4.jar;E:\Maven\ideamaven\com\github\jsqlparser\jsqlparser\1.0\jsqlparser-1.0.jar;E:\A_lshady\boot_falsework\boot-common\target\classes;E:\Maven\ideamaven\org\springframework\boot\spring-boot-starter-amqp\2.5.6\spring-boot-starter-amqp-2.5.6.jar;E:\Maven\ideamaven\org\springframework\spring-messaging\5.3.12\spring-messaging-5.3.12.jar;E:\Maven\ideamaven\org\springframework\spring-beans\5.3.12\spring-beans-5.3.12.jar;E:\Maven\ideamaven\org\springframework\amqp\spring-rabbit\2.3.11\spring-rabbit-2.3.11.jar;E:\Maven\ideamaven\org\springframework\amqp\spring-amqp\2.3.11\spring-amqp-2.3.11.jar;E:\Maven\ideamaven\org\springframework\retry\spring-retry\1.3.1\spring-retry-1.3.1.jar;E:\Maven\ideamaven\com\rabbitmq\amqp-client\5.12.0\amqp-client-5.12.0.jar;E:\Maven\ideamaven\org\springframework\spring-context\5.3.12\spring-context-5.3.12.jar;E:\Maven\ideamaven\org\springframework\spring-tx\5.3.12\spring-tx-5.3.12.jar;E:\Maven\ideamaven\net\bytebuddy\byte-buddy\1.10.22\byte-buddy-1.10.22.jar;E:\Maven\ideamaven\org\springframework\spring-core\5.3.12\spring-core-5.3.12.jar;E:\Maven\ideamaven\org\springframework\spring-jcl\5.3.12\spring-jcl-5.3.12.jar;E:\Maven\ideamaven\org\springframework\boot\spring-boot-starter-web\2.5.6\spring-boot-starter-web-2.5.6.jar;E:\Maven\ideamaven\org\springframework\boot\spring-boot-starter-json\2.5.6\spring-boot-starter-json-2.5.6.jar;E:\Maven\ideamaven\com\fasterxml\jackson\core\jackson-databind\2.12.5\jackson-databind-2.12.5.jar;E:\Maven\ideamaven\com\fasterxml\jackson\core\jackson-annotations\2.12.5\jackson-annotations-2.12.5.jar;E:\Maven\ideamaven\com\fasterxml\jackson\core\jackson-core\2.12.5\jackson-core-2.12.5.jar;E:\Maven\ideamaven\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.12.5\jackson-datatype-jdk8-2.12.5.jar;E:\Maven\ideamaven\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.12.5\jackson-datatype-jsr310-2.12.5.jar;E:\Maven\ideamaven\com\fasterxml\jackson\module\jackson-module-parameter-names\2.12.5\jackson-module-parameter-names-2.12.5.jar;E:\Maven\ideamaven\org\springframework\boot\spring-boot-starter-tomcat\2.5.6\spring-boot-starter-tomcat-2.5.6.jar;E:\Maven\ideamaven\org\apache\tomcat\embed\tomcat-embed-core\9.0.54\tomcat-embed-core-9.0.54.jar;E:\Maven\ideamaven\org\apache\tomcat\embed\tomcat-embed-el\9.0.54\tomcat-embed-el-9.0.54.jar;E:\Maven\ideamaven\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.54\tomcat-embed-websocket-9.0.54.jar;E:\Maven\ideamaven\org\springframework\spring-web\5.3.12\spring-web-5.3.12.jar;E:\Maven\ideamaven\org\springframework\spring-webmvc\5.3.12\spring-webmvc-5.3.12.jar;E:\Maven\ideamaven\org\springframework\spring-aop\5.3.12\spring-aop-5.3.12.jar;E:\Maven\ideamaven\org\springframework\spring-expression\5.3.12\spring-expression-5.3.12.jar;E:\Maven\ideamaven\org\springframework\boot\spring-boot-configuration-processor\2.5.6\spring-boot-configuration-processor-2.5.6.jar;E:\Maven\ideamaven\org\projectlombok\lombok\1.18.20\lombok-1.18.20.jar;E:\Maven\ideamaven\cn\hutool\hutool-all\5.7.12\hutool-all-5.7.12.jar;E:\Maven\ideamaven\com\alibaba\fastjson\1.2.78\fastjson-1.2.78.jar;E:\Maven\ideamaven\com\github\xiaoymin\knife4j-spring-boot-starter\2.0.8\knife4j-spring-boot-starter-2.0.8.jar;E:\Maven\ideamaven\com\github\xiaoymin\knife4j-spring-boot-autoconfigure\2.0.8\knife4j-spring-boot-autoconfigure-2.0.8.jar;E:\Maven\ideamaven\com\github\xiaoymin\knife4j-spring\2.0.8\knife4j-spring-2.0.8.jar;E:\Maven\ideamaven\com\github\xiaoymin\knife4j-annotations\2.0.8\knife4j-annotations-2.0.8.jar;E:\Maven\ideamaven\com\github\xiaoymin\knife4j-core\2.0.8\knife4j-core-2.0.8.jar;E:\Maven\ideamaven\org\javassist\javassist\3.25.0-GA\javassist-3.25.0-GA.jar;E:\Maven\ideamaven\io\swagger\swagger-models\1.5.22\swagger-models-1.5.22.jar;E:\Maven\ideamaven\io\swagger\swagger-annotations\1.5.22\swagger-annotations-1.5.22.jar;E:\Maven\ideamaven\io\springfox\springfox-swagger2\2.10.5\springfox-swagger2-2.10.5.jar;E:\Maven\ideamaven\io\springfox\springfox-spi\2.10.5\springfox-spi-2.10.5.jar;E:\Maven\ideamaven\io\springfox\springfox-core\2.10.5\springfox-core-2.10.5.jar;E:\Maven\ideamaven\io\springfox\springfox-schema\2.10.5\springfox-schema-2.10.5.jar;E:\Maven\ideamaven\io\springfox\springfox-swagger-common\2.10.5\springfox-swagger-common-2.10.5.jar;E:\Maven\ideamaven\io\springfox\springfox-spring-web\2.10.5\springfox-spring-web-2.10.5.jar;E:\Maven\ideamaven\io\github\classgraph\classgraph\4.1.7\classgraph-4.1.7.jar;E:\Maven\ideamaven\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar;E:\Maven\ideamaven\org\springframework\plugin\spring-plugin-core\2.0.0.RELEASE\spring-plugin-core-2.0.0.RELEASE.jar;E:\Maven\ideamaven\org\springframework\plugin\spring-plugin-metadata\2.0.0.RELEASE\spring-plugin-metadata-2.0.0.RELEASE.jar;E:\Maven\ideamaven\org\mapstruct\mapstruct\1.3.1.Final\mapstruct-1.3.1.Final.jar;E:\Maven\ideamaven\io\springfox\springfox-bean-validators\2.10.5\springfox-bean-validators-2.10.5.jar;E:\Maven\ideamaven\io\springfox\springfox-spring-webmvc\2.10.5\springfox-spring-webmvc-2.10.5.jar;E:\Maven\ideamaven\com\github\xiaoymin\knife4j-spring-ui\2.0.8\knife4j-spring-ui-2.0.8.jar com.lshady.bootstart.test.Test2
  19. java.lang.InterruptedException: sleep interrupted
  20. at java.lang.Thread.sleep(Native Method)
  21. at com.lshady.bootstart.test.Test2.lambda$main$0(Test2.java:15)
  22. at java.lang.Thread.run(Thread.java:748)
  23. Process finished with exit code 0

对于第二种情况

  1. public static void main(String[] args) {
  2. Thread t1 = new Thread(() -> {
  3. System.out.println("t1...");
  4. while(true) {
  5. Thread current = Thread.currentThread();
  6. boolean interrupted = current.isInterrupted();
  7. if(interrupted) {
  8. log.debug(" 打断状态: {}", interrupted);
  9. break;
  10. }
  11. }
  12. });
  13. t1.start();
  14. t1.interrupt();
  15. log.info("t1 interrupt : {}",t1.isInterrupted());
  16. log.info("t1 interrupt : {}",t1.isInterrupted());
  17. }
  18. 输出
  19. t1...
  20. t1 interrupt : true
  21. t1 interrupt : false

值得注意的是:t1.isInterrupted()方法会获取标记状态之后重新将标记设置为false

模式之两阶段终止

  1. public class Test2 {
  2. private Thread thread;
  3. public void start(){
  4. thread = new Thread(() -> {
  5. Thread thread = Thread.currentThread();
  6. while (true){
  7. //判断是否要被打断
  8. if(thread.isInterrupted()){
  9. //确认要打断 料理后事
  10. break;
  11. }
  12. //不被打断就每次睡眠1秒钟
  13. //在睡眠状态下被打断 会抛异常
  14. // 然后会被清除打断标记 这时候需要重新打上中断标记
  15. try {
  16. Thread.sleep(1000);
  17. }catch (InterruptedException e){
  18. //在sleep下被打断抛异常会清除打断标记
  19. e.printStackTrace();
  20. thread.interrupt();
  21. }
  22. }
  23. });
  24. }
  25. public void stop(){
  26. thread.interrupt();
  27. }
  28. }

LockSupport.park和interrupt

  1. public class Test3 {
  2. public static void main(String[] args) throws InterruptedException {
  3. Thread thread = new Thread(() -> {
  4. System.out.println("park");
  5. LockSupport.park();
  6. System.out.println("unPark");
  7. System.out.println(Thread.currentThread().isInterrupted());
  8. //值得注意的是LockSupport.park();想要连续第二次生效需要
  9. //需要再次调用interrupt方法标记中断
  10. Thread.currentThread().interrupt();
  11. LockSupport.park();
  12. });
  13. //被park的线程 调用interrupt方法会唤醒线程
  14. thread.start();
  15. Thread.sleep(1000);
  16. thread.interrupt();
  17. }
  18. }