gpt4 book ai didi

java - 当线程阻塞时,在线程上调用的中断不会抛出中断异常

转载 作者:行者123 更新时间:2023-12-01 11:45:19 25 4
gpt4 key购买 nike

我正在尝试使用 ReentrantLock 和条件实现阻塞队列(仅在消费者端),但遇到了 JVM 不会终止的状态。奇怪的是,一个线程被中断,但另一个线程没有。我确信我犯了一些错误,但就是不知道是什么。

编辑:

主要问题:为什么当两个线程都在 condition.await 上阻塞时,只有一个线程抛出 InterruptedException

所以下面的代码只是我创建的一个示例。主要问题是开发一个生产者-消费者实现,其中我必须创建一个模拟类,该类产生两种线程:客户和厨师,它们基于可重入锁进行同步。执行一些操作后(客户添加订单,厨师执行服务这些订单),我在客户线程上调用 join 以确保所有订单均已处理,然后为了停止厨师线程,我在厨师线程上调用中断来终止它们。但只有一个线程抛出 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!!!");

}

}

最佳答案

你有

condition.await();

但你发出信号的唯一位置是在catch block 中。

在应用程序的典型运行中,您的 InterruptedThread(我们称之为 it1)将进入 while 循环并 await 条件 上,将自身置于等待状态。您的main线程将执行一系列操作并最终中断it1。您会注意到 Condition#await() 的 javadoc州

In all cases, before this method can return the current thread must re-acquire the lock associated with this condition.

因此线程 it2 重新获取锁,因为它已被中断

If the current thread:

  • has its interrupted status set on entry to this method; or
  • is interrupted while waiting and interruption of thread suspension is supported,

then InterruptedException is thrown and the current thread's interrupted status is cleared.

因此执行离开 while block 并转到 catch。在此期间,您的线程 it2 仍然拥有锁,因为没有任何东西解锁它。然后 catch block 调用

this.condition.signalAll();

它表示条件。然后线程 it1 正常完成。但是,Lock 仍然处于锁定状态,没有任何东西可以获取它,这就是为什么您的其他 InterruptedThread 无法从其内部继续

condition.await();

您基本上必须更好地管理锁定和解锁您的Lock

关于java - 当线程阻塞时,在线程上调用的中断不会抛出中断异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29186543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com