【问题标题】:Why thread can't be interrupted in ExecutorService?为什么ExecutorService中的线程不能被中断?
【发布时间】:2015-06-22 05:54:20
【问题描述】:

我做了一个简单的测试,代码如下:

    public class InterruptTest
    {
        public static class MyTask implements Runnable {
            @Override
            public void run() {
                System.out.println("before sleep " + Thread.currentThread().isInterrupted());
                System.out.println(Thread.currentThread());
                Thread.currentThread().interrupt();
                System.out.println("after sleep " + Thread.currentThread().isInterrupted());
            }
        }

        public static void main(String[] str)
        {
            ExecutorService service = Executors.newFixedThreadPool(1);
            // MyTask task1 = new MyTask();
            Future<?> future1 = service.submit(new InterruptTest.MyTask());
            Future<?> future2 = service.submit(new InterruptTest.MyTask());

            try
            {
                Thread.sleep(10);
            }
            catch (InterruptedException e)
            {
                System.out.println("interrupted;");
            }
        }
}

输出是:

before sleep false
Thread[pool-1-thread-1,5,main]
after sleep true
**before sleep false** // line 4
Thread[pool-1-thread-1,5,main]
after sleep true

为什么第 4 行仍然输出 false ?不对 ?因为当前池中只有一个线程,第一个任务应该已经被中断了,为什么第二个任务运行时它仍然可用(未中断)?

提前致谢!

另一个问题是我将运行函数修改如下:

    public static class MyTask implements Runnable {
    @Override
    public void run() {
        System.out.println("before sleep " + Thread.currentThread().isInterrupted());
        System.out.println(Thread.currentThread());

        try
        {
            Thread.sleep(10);
        }
        catch (InterruptedException e)
        {
            System.out.println("interrupted;");
            System.out.println("after sleep " + Thread.currentThread().isInterrupted());
            System.out.println(Thread.currentThread());
        }
    }
}

一个任务的输出是:

before sleep false
Thread[pool-1-thread-1,5,main]
interrupted;
after sleep false

任务应该被thread.interrupt从睡眠中唤醒。但是当我使用 Thread.currentThread().isInterrupted() 来检查它时,它仍然返回 false。

sleep() 会吃掉中断状态吗??

【问题讨论】:

  • 不,sleep() 不会吞下中断状态。抛出InterruptedException(有点反常)不会导致在被中断线程上设置中断标志:这就是为什么如果你捕获InterruptedException并且你不愿意或无法传播,你需要手动重新中断当前线程该异常,但希望保留线程被调用者中断的证据。

标签: java multithreading concurrency executorservice


【解决方案1】:

查看ThreadPoolExecutor的源码,有一个私有方法叫clearInterruptsForTaskRun记录为:

确保除非池正在停止,否则当前线程没有设置其中断

【讨论】:

  • 感谢您的回答!我在runWorker中找到了相关的代码:
猜你喜欢
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
  • 2019-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
相关资源
最近更新 更多