请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

storage.put()阻塞后响应中断疑问

前面小结的讲解中,sleep期间被中断java会将中断状态更改,
所以需要在catch中调用Thread.currentThread().interrupt() 恢复中断状态后才能再次通过Thread.currentThread().isInterrupted()判断,但是本小节中storage.put()阻塞响应中断后并未在catch中调用Thread.currentThread().interrupt()恢复中断状态,我想请问老师:storage.put()阻塞响应中断后不会像sleep一样更改中断状态吗?

正在回答

1回答

class Producer implements Runnable {

    public volatile boolean canceled = false;

    BlockingQueue storage;

    public Producer(BlockingQueue storage) {
        this.storage = storage;
    }

    @Override
    public void run() {
        System.out.println("生产者开始生产数据了");
        int num = 0;
        try {
            while (!Thread.currentThread().isInterrupted()) {
                if (num % 100 == 0) {
                    storage.put(num);
                    System.out.println(num + "是100的倍数,被放到仓库中了。");
                }
                num++;
            }
        } catch (InterruptedException e) {
            System.out.println("生产者收到中断信号");
        } finally {
            System.out.println("生产者结束运行");
        }
    }
}

这里put期间收到中断信号,就被catch住,然后就整个跳出while循环,停止运行了。storage.put()阻塞响应中断后,也会像sleep一样清除中断状态。

0 回复 有任何疑惑可以回复我~
  • 提问者 水桶一号 #1
    老师您好,在这个例子中,生产者每次迭代都阻塞,像这种情况相应线程中断的代码是造成阻塞的代码:storage.put(num);根据前面章节中所讲的此种情况不需要在while循环中使用!Thread.currentThread().isInterrupted()该判断停止线程,阻塞代码会自动相应interrupt()。所以在这个案例中的while循环中依然可以使用上一小结中的判断条件 while (num <= 100000) {}。不过老师您的这个写法while (num <= 100000 && !Thread.currentThread().isInterrupted())更严谨,只是容易给学员造成是由于!Thread.currentThread().isInterrupted()这个判断终止的线程的印象,应该在教学视频中明确指出;所以我才会有上次的疑问。
    回复 有任何疑惑可以回复我~ 2019-09-20 09:25:54
  • 悟空 回复 提问者 水桶一号 #2
    说得没错,这里会加!Thread.currentThread().isInterrupted()是因为历史原因,在代码迭代的过程中,需要先展示出无法检测到中断发生的情况(因为在put中阻塞了却没人唤醒),所以加了!Thread.currentThread().isInterrupted()让这个检测更明显。当明确了put()阻塞可以响应中断后,就可以把!Thread.currentThread().isInterrupted()去掉的。
    回复 有任何疑惑可以回复我~ 2019-09-20 10:57:59
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信