一个关于ExecutorService shutdownNow时很奇怪的现象

我们知道很多类库中的阻塞方法在抛出InterruptedException后会清除线程的中断状态(例如 sleep、 阻塞队列的take),但是今天却发现了一个特别奇怪的现象,先给出代码:

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println("first interrupted!!!");
                }

                System.out.println(Thread.currentThread().isInterrupted());

                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    System.out.println("second interrupted!!!");
                }
            }
        });

        executor.shutdownNow();
    }

如果按照我的理解,调用shutdownNow后会给线程池中的工作者线程发出中断请求,并在第一个睡眠的地方抛出 InterruptedException ,但是在抛出异常后这种中断状态就应该被清除了,所以第二次睡眠不应该失败,但是结果却是失败的,本来以为是系统的原因,可是在linux下测试也是如此。

更令人不解的是如果我把第二次睡眠换成其他的阻塞方法(queue.take)那么就不会抛出异常,而是正常阻塞。

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        final BlockingQueue<String> queue = new LinkedBlockingQueue<>();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println("first interrupted!!!");
                }

                System.out.println(Thread.currentThread().isInterrupted());

                try {
                    queue.take();
                } catch (InterruptedException e) {
                    System.out.println("second interrupted!!!");
                }
            }
        });

        executor.shutdownNow();
    }

还有更让人受不了的,如果我们在任务最开始随便写点什么,就会按照我们期待的执行了(心中一万只草泥马呀)

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("xxxx");
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println("first interrupted!!!");
                }

                System.out.println(Thread.currentThread().isInterrupted());

                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    System.out.println("second interrupted!!!");
                }
            }
        });

        executor.shutdownNow();
    }

以后有机会再研究吧,可能还是知识不够吧!!!!

时间: 2024-08-25 21:41:39

一个关于ExecutorService shutdownNow时很奇怪的现象的相关文章

做一个手机端页面时,遇到了一个奇怪的问题:字体的显示大小,与在CSS中指定的大小不一致

最近在做一个手机端页面时,遇到了一个奇怪的问题:字体的显示大小,与在CSS中指定的大小不一致.大家可以查看这个Demo(记得打开Chrome DevTools). 就如上图所示,你可以发现,原本指定的字体大小是24px,但是最终计算出来的却是53px,看到这诡异的结果,我心中暗骂一句:这什么鬼! 随后开始对问题各种排查:某个标签引起的?某个CSS引起的?又或者是某句JS代码引起的.通过一坨坨的删代码,发现貌似都不是.我不禁又骂,到底什么鬼!不过中间还是发现了一些端倪:当页面中的标签数量或者文本数

一个很奇怪的问题

先来看看我的一段代码: 1 ArrayList<Integer> array = new ArrayList<Integer>(); 2 3 for(int i = 0;i<100;i++){ 4 array.add(i); 5 } 6 for(int i=0;i<array.size();i++){ 7 // array.remove(new Integer(i)); 8 array.remove(i); 9 } 你觉得这样能不能把array里面的东西都删除呢? 输出

优化器跟踪分析一个很怪异的现象

工作中遇到一则很奇怪的真实案例,有一个统计sql,统计结果在190-200之间时,耗时基本上维持在1.6S,统计结果在此数据范围外的统计耗时,基本上维持在0.1-0.3S之间, 按照惯例,explain查看执行计划. 为方便阐述,约定如下 : 数据范围在190-200,耗时1.6S的叫 sql1,数据范围不在此范围,耗时0.1-0.3S的叫sql2 sql1执行计划: sql2执行计划: 两条完全相同的sql就筛选条件中换了一个departid的值,sql1 191条记录,sql2 256条记录

计算一个人的年龄(年月日时分秒),有不对的地方希望大家指出!

想想我们可以做一个计时器,记录一下我们走过了多少时光.看了一下网上别人的一些代码,记录年月的都并不科学,甚至很麻烦,自己倒腾了一上午,总算弄出来了一个. 自己觉得还比较科学,暂时没有发现BUG,如果哪里有错,希望大家指出来! 上代码: <!doctype html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&

基于Spring开发的一个BIO-RPC框架(对小白很友好)

PART1:先来整体看下项目的构成 其中bio-rpc-core就是所谓的rpc框架 bio-rpc-example-client即所谓的服务调用方(你的项目中想要调用服务的地方) bio-rpc-example-server即所谓的服务提供方(你的项目中写好服务想要供别人调用的地方) github地址:https://github.com/Luyu05/BioRpcExample PART2:这个框架咋用? 服务使用方 1.首先,在想要调用服务的地方(bio-rpc-example-clien

关于 document.getElementById 一个奇怪的现象

html: <html><head><script type="text/javascript" src="1.js"></script></head><body><input type="text" id="num1"/><br/><input type="text" id="num2"

在一个高并发系统中 如果突然出现一个应用或者说一个服务突然变得很慢,应该怎么排查?

声明:该总结为网友朋友总结,本人是归纳成文,方便各网友学习交流. 这个是考线上排查问题能力,没有标准答案,作为开发,假设这种情景出现你怎么诊断问题? 首先:想知道,在实际情况下,怎么知道[一个应用或者说一个服务突然变得很慢]?调用访问的时候会发现的,对于业务流程比较熟悉很重要,先能够初步圈出,可能出现问题的地方,服务监控是必须的,做业务必须要知道自己服务的状态. 1.首先就是想看日志,后来想想看日志确实不太可行,并发量太大的情况下,查日志会很慢,(看日志,pstack strace gdb).

有时候错误很奇怪啊,Comparator问题

有时候错误很奇怪啊,Comparator问题,在我的电脑上排序好用,但是在别的电脑上排序不好用, 真奇怪a

UINavigationController在一个界面push到另一个界面传数据时的注意点

在push到下一个controller的时候,应注意以下几点: 1>在执行push代码的时候,才创建controller,不要在push之前使用controller里面的view 如下面的错误事例: CommentModel *model = [_arraySaveDataobjectAtIndex:but.tag]; CommentDetailViewController *commentDetailVC = [[CommentDetailViewControlleralloc] init];