当前位置: 首页 > 知识库问答 >
问题:

当线程阻塞时,在线程上调用的中断不会引发中断异常

舒宏富
2023-03-14

编辑:

主要问题:为什么只有一个线程抛出interruptedexception,而两个线程都阻塞在条件上。await

所以下面的代码只是我创建的一个示例。主要的问题是开发一个生产者-消费者实现,在这个实现中,我必须创建一个模拟类,它产生两种线程:客户线程和厨师线程,这两种线程是基于可重入锁进行同步的。在执行一些操作(客户添加订单,厨师执行服务这些订单)后,我调用客户线程上的join以确保所有订单都已处理,然后为了停止库克线程,我调用库克线程上的interrupt以终止它们。但是只有一个线程抛出interruptedexception,第二个线程不抛出。为什么会这样?因为这两个线程都阻塞在等待。

public class InterruptedThread implements Runnable{

    private final Lock lock;
    private final Condition condition;
    private final Queue<Integer> orderQueue;


    public InterruptedThread(Lock lock, Condition condition,Queue<Integer> orderQueue)
    {
        this.lock = lock;
        this.condition = condition;
        this.orderQueue = orderQueue;
    }

    @Override
    public void run() {

        try{
        while(true)
        {
            this.lock.lockInterruptibly();
            while(orderQueue.size() == 0 && !Thread.currentThread().isInterrupted())
            {
                   System.out.println("Inside blocking wait" + Thread.currentThread().getName());
                   condition.await();
            }

            int i = orderQueue.poll().intValue();
            System.out.println("Value read:" + i + "by thread" + Thread.currentThread().getName());
            this.lock.unlock();


        }
        }
        catch(InterruptedException ex)
        {
            System.out.println("Interrupted exception" + Thread.currentThread().getName());
            this.condition.signalAll();
            Thread.currentThread().interrupt();

        }

    }

}
public class ExplicitLockCondition {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here

        Queue<Integer> orderQueue = new LinkedList<>();
        Lock lock = new ReentrantLock();
        Condition testCondition = lock.newCondition();

        Thread[] ths = new Thread[2];
        for(int i=0; i<ths.length;i++)
        {
            ths[i] = new Thread(new InterruptedThread(lock, testCondition,orderQueue));
            ths[i].start();
        }

        lock.lock();

        orderQueue.add(1);
        lock.unlock();

        lock.lock();
        orderQueue.add(2);
        lock.unlock();

        try {
            Thread.currentThread().sleep(5000);
        } catch (InterruptedException ex) {
            Logger.getLogger(ExplicitLockCondition.class.getName()).log(Level.SEVERE, null, ex);
        }

        lock.lock();
        orderQueue.add(-99);
        lock.unlock();


        for(int i=0; i<ths.length;i++)
        {
            ths[i].interrupt();

        }
        System.out.println("After loop exited!!!");
        for(int i=0; i<ths.length;i++)
        {
        System.out.println("Interrupted thread:" + ths[i].getName() +"with interrupt flag:" + ths[0].isInterrupted());
        }

        for(int i=0; i<ths.length;i++)
        {
            try {
                ths[i].join();
            } catch (InterruptedException ex) {
                Logger.getLogger(ExplicitLockCondition.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        System.out.println("Program exited!!!");

    }

}

共有1个答案

程亦
2023-03-14

你有

condition.await();

但是发出信号的唯一位置是catch块。

在应用程序的典型运行中,interruptedthread(我们将其称为IT1)将进入while循环和await条件,使其处于等待状态。您的main线程将执行一系列操作,并最终中断IT1。您将注意到条件#await()状态的javadoc

  • 在进入此方法时设置了中断状态;或
  • 在等待时中断,并且支持中断线程挂起,

然后抛出interruptedexception,并清除当前线程的中断状态。

因此,执行离开while块,转到catch。在此期间,您的线程IT2仍然拥有锁,因为没有unlock对它进行解锁。然后,catch块调用

this.condition.signalAll();
condition.await();
 类似资料:
  • 我正在编写一个有3个线程的程序。一个读取一个文本文件并将单词输入到大小为2的ArraylistBlockingQueue中。下一个获取该列表并反转其中的每个其他单词。最后一个线程获取单词并将它们写入一个新的文本文件。 我所有的东西都在工作,除了我不知道如何中断和停止我的线程。程序写入文本文件,但从未结束。 主要方法 输入 反向类@重写公共void run(){ 输出代码@覆盖公共无效run(){

  • 问题内容: 我抛出了异常而不是显示失败,这是我做错了,还是我应该在线程内没有断言? 堆栈跟踪 问题答案: JUnit框架仅捕获运行测试的主线程中的断言错误。它不知道新的派生线程中的异常。为了正确执行此操作,您应该将线程的终止状态传达给主线程。您应该正确同步线程,并使用某种共享变量来指示嵌套线程的结果。 编辑: 这是可以提供帮助的通用解决方案: 您应该在构造函数中将其传递给runnable,然后只需

  • 我正在尝试创建一个消费者-生产者程序,其中消费者线程生产者的数字填充数组,消费者线程打印填充数组的数字。目前,我可以填充数组并在使用者/生产者线程之间来回传递数据,但我希望生产者创建数字的速度比使用者处理数字的速度快。 此刻,每1秒产生一个数字,每3消耗一个数字。在消耗一个之前应该产生两个数字,但是我的生产者线程正在等待,直到它产生的数字被消耗。 我试过移动互斥锁和解锁,还有信号,但我没有得到它的

  • 我需要使一个库,我将有同步和异步的特点。 -等待得到结果,返回结果。 -立即返回一个将来值,如果需要,该将来值可以在其他事情完成后处理。 my Library的核心逻辑 将执行实际任务的简单类: 当我开始处理此解决方案时,我并没有终止超时的任务。我向客户机报告超时,但任务继续在线程池中运行(可能会长时间占用我有限的10个线程中的一个)。所以我在网上做了一些研究,我发现我可以通过使用取消未来来取消超

  • 问题内容: 我正在使用RXTX从串行端口读取数据。读取是在以下列方式产生的线程中完成的: SerialReader类实现Runnable并无限期地循环,从端口读取并将数据构造为有用的程序包,然后再将其发送给其他应用程序。但是,我将其简化为以下简单性: 当用户单击停止按钮时,将触发以下功能,从理论上讲,应关闭输入流并突破阻塞的byteChan.read(buffer)调用。代码如下: 但是,当我运行