ThreadPoolExecutor(四)——Interrupt

 1.补充知识

说ThreadPoolExecutor之前先要说先补充知识,关于Thread的interrupt相关操作。

还有一篇博客比较言简意赅,interrupt、interrupted 、isInterrupted 区别

interrupt对于处于sleep,wait状态的线程会进行interrupt并抛出InterruptedException,同时擦除中断标志位,也就是说,这时候如果再用isInterrupted或者静态interrupted方法获取中断标志位的时候,得到的是false。

interrupt对于正常运行的线程起不到中断作用,只是把该线程的中断标志位设置为true了,线程会继续正常运行。

Thread静态interrupted方法判断标志位的时候也会清除标志位。也就是说一个线程被中断了,在线程中用interrupted判断时返回true,再次调用该方法判断会返回false。

Thread的成员函数isInterrupted判断标志位的时候不会清除标志位,如果返回true,那么无论执行多少次都会返回true(期间没有其他清除标志位的操作的话)。

2.处于sleep状态下的打断

public static void test1() throws Exception {
        final Thread thread = new Thread(new Runnable() {
            @Override public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println("thread is interrupted!!!!!!!!!!2");
                    System.out.println("isInterrupted:" + Thread.interrupted());
                }
            }
        });
        thread.start();
        new Thread(new Runnable() {
            @Override public void run() {
                // 会打断上面那个线程的sleep
                thread.interrupt();
            }
        }).start();
        System.out.println("over");
        System.in.read();
    }

运行结果如下:

java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.qunar.flight.brandnew.java.thread.TInterrupt$1.run(TInterrupt.java:23)
at java.lang.Thread.run(Thread.java:722)
over
thread is interrupted!!!!!!!!!!2

说明处于sleep状态的thread线程被中断并抛出了异常。这里Thread.interrupted()方法返回是false,因为抛出异常之后就清除了中断标志位了。

3.处于wait状态下的中断

private static Object lock = new Object();

    public static void test2() throws Exception {
        final Thread thread = new Thread(new Runnable() {
            @Override public void run() {
                try {
                    synchronized (lock) {
                        lock.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println("thread is interrupted!!!!!!!!!!1");
                }
            }
        });
        thread.start();
        new Thread(new Runnable() {
            @Override public void run() {
                System.out.println("interrupt");
                thread.interrupt();
            }
        }).start();
        System.out.println("over");
        System.in.read();
    }

结果:

over
interrupt
thread is interrupted!!!!!!!!!!
isInterrupted:false
java.lang.InterruptedException

这里和上面wait的情况基本一致。

4.线程正常运行时的interrupt

public static void test5() throws Exception {
        final Thread thread = new Thread(new Runnable() {
            @Override public void run() {
                for (int i = 0; i < 1000; i++) {
                    for (int j = 0; j < 100000; j++) {
                        System.currentTimeMillis();
                    }
                }
                System.out.println("isInterrupted:" + Thread.interrupted());
                System.out.println("isInterrupted:" + Thread.currentThread().isInterrupted());
            }
        });
        thread.start();
        Thread thread2 = new Thread(new Runnable() {
            @Override public void run() {
                thread.interrupt();
            }
        });
        thread2.start();
        System.out.println("over");
        System.in.read();
    }

结果:

over
isInterrupted:true
isInterrupted:false这里中断的时候thread线程依然正常运行,只是中断标志位被置位true了。Thread.interrupted()方法判断的时候返回了true,同时擦除了中断标志位,所以再用Thread.currentThread().isInterrupted()判断的时候,就返回false了。

5.处于park状态下的interrupt

public static void test6() throws Exception {
        final Thread thread = new Thread(new Runnable() {
            @Override public void run() {
                LockSupport.park();
                System.out.println("isInterrupted:" + Thread.interrupted());
                System.out.println("isInterrupted:" + Thread.currentThread().isInterrupted());
            }
        });
        thread.start();
        Thread thread2 = new Thread(new Runnable() {
            @Override public void run() {
                thread.interrupt();
            }
        });
        thread2.start();
        System.out.println("over");
        System.in.read();
    }

结果:

over
isInterrupted:true
isInterrupted:false

和线程正常运行下的返回结果相同。

说明interrupt可以中断处于park状态的线程,但是不会抛出InterruptedException异常,只是设置中断标志位。

AbstractQueuedSynchronizer的doAcquireInterruptibly方法就是根据parkAndCheckInterrupt的返回值,在park状态被唤醒的时候,判断线程是被中断的还是被unpark唤醒的,决定后续的操作是抛出异常还是继续去获得锁
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值