关于使用interrupt代替volatile进行中断的例子的看法

来源:5-12 停止失效

KimZing

2019-09-09

一、While判断条件

例子中在while判断中使用Thread.currentThread().isInterrupted()替换!canceled,一开始对这一块有误解,以为是因为加了Thread.currentThread().isInterrupted()程序才会正常响应中断。

  1. 不加这一个判断,也是完全可以正常中断的,真正中断的地方是put()阻塞方法对interrupt()进行了响应,抛出了InterruptedException, 进入catch块,打印了日志,并最终执行finnaly块代码。
  2. 多加Thread.currentThread().isInterrupted()只是多了一个检查的点。
  3. 某种角度来说,如果wait()/sleep()…支持自定义的中断信号,可以响应canceled的话,也是没啥问题的。

二、关于try的作用范围

从代码编写的角度,try作用范围扩大到while外层,对性能有一定帮助,但觉得这个例子在内部捕捉异常,使用break跳出循环,或许更易于理解。

自己写了个low的例子,说明自己的理解,谢谢老师的讲解

public class VolatileStopThreadReplaseWithInterrupt {

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

        // 容纳10个元素的阻塞队列
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
        Producer producer = new Producer(queue);
        Thread thread = new Thread(producer);
        // 启动生产者
        thread.start();

        // 直接用主线程当消费者
        while (Math.random() < 0.9D) {
            System.out.println("消费:" + queue.take());
            // 消费很慢,导致生产者会被阻塞
            Thread.sleep(100);
        }

        System.out.println("消费线程停止消费,并通知生产者停止生产");
        thread.interrupt();
    }

}

class Producer implements Runnable{

    private BlockingQueue<Integer> blockingQueue;

    public Producer(BlockingQueue<Integer> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            try {
                System.out.println("生产:" + i);
                // 阻塞方法
                blockingQueue.put(i);
            } catch (InterruptedException e) {
                System.out.println("生产线程接收到中断信号");
                break;
            } finally {
                System.out.println("生产线程已经停止生产元素");
            }
        }
    }
}
写回答

1回答

悟空

2019-09-09

不加这一个判断,也是完全可以正常中断的,真正中断的地方是put()阻塞方法对interrupt()进行了响应,抛出了InterruptedException, 进入catch块,打印了日志,并最终执行finnaly块代码。

多加Thread.currentThread().isInterrupted()只是多了一个检查的点。

对的,虽然这个例子中,是put对interrupt进行了响应,但是不一定每个业务逻辑都会用到put,所以通常情况下,加上Thread.currentThread().isInterrupted()这个判断点可以更稳妥。

某种角度来说,如果wait()/sleep()…支持自定义的中断信号,可以响应canceled的话,也是没啥问题的。

对的,如果可以支持自定义信号,那就没问题。

从代码编写的角度,try作用范围扩大到while外层,对性能有一定帮助,但觉得这个例子在内部捕捉异常,使用break跳出循环,或许更易于理解。

自己写了个low的例子,说明自己的理解,谢谢老师的讲解

不客气,我觉得这两种try范围都可以,只要能表达“遇到中断就退出”的含义就可以。

3
1
KimZing
非常感谢!
2019-09-10
共1条回复

线程八大核心+Java并发原理及企业级并发解决方案

完整的并发知识网络+丰富的工作内容分享+50余道并发高频面试题

2512 学习 · 939 问题

查看课程