java - 抛出 InterruptedException 时不会清除线程中断状态

标签 java multithreading executorservice

谁能解释为什么这个程序会打印多个“中断”语句。

根据 Thread.sleep javadoc

InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Test {

    public static void main(String[] args) throws Exception {

        for (int z = 0; z < 100; z++) {

            ExecutorService executor1 = Executors.newSingleThreadExecutor();

            executor1.execute(new Runnable() {

                @Override
                public void run() {

                    ExecutorService executor2 = Executors.newFixedThreadPool(10);

                    for (int i = 0; i < 10; i++) {

                        executor2.execute(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    Thread.sleep(1000 * 100);
                                } catch (InterruptedException e) {
                                    if (Thread.currentThread().isInterrupted()) {
                                        System.out.println("interrupted");
                                    }
                                }
                            }
                        });
                    }

                    executor2.shutdownNow();
                    try {
                        executor2.awaitTermination(5, TimeUnit.SECONDS);
                    } catch (InterruptedException e) {
                    }
                }
            });

            executor1.shutdown();

            try {
                executor1.awaitTermination(10, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
            }
        }
    }
}

output - screenshot

最佳答案

来自doc

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

当您在 Thread.sleep(1000 * 100) 期间关闭执行程序服务并抛出 InterruptedException 时,状态将被清除。

但是ThreadPoolExecutor通过t.interrupt()重新设置了状态,所以你仍然可以得到状态。

这里是重置状态的一段代码:

    for (Worker w : workers) {
        Thread t = w.thread;
        if (!t.isInterrupted() && w.tryLock()) {
            try {
                t.interrupt();
            } catch (SecurityException ignore) {
            } finally {
                w.unlock();
            }
        }
        if (onlyOne)
            break;
    }

关于java - 抛出 InterruptedException 时不会清除线程中断状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48420502/

相关文章:

java - 阶段/插件和 Maven 项目生成器

java - 如何使用 Java 在 HTML 中查找 URL

java - Java如何正确添加同步

c# - 为什么 Thread.Sleep 在其他应用程序运行时等待的时间比请求的时间长?

java - 使用新数据刷新 JEditorPane

java - 当等待一个线程的 Future 时,线程执行是否会继续

java - 如何从 java 目录加载某个类的实例?

java - Spring Security 是如何跨 Web 应用请求在一个线程中管理 SecurityContext 的?

Java ExecutorService - 创建一个新线程但不启动它

java - OpenJFX 11 - javafxpackager 二进制 CSS