Я пытаюсь реализовать очередь блокировки (только на стороне потребителя) с ReentrantLock и условиями, но нахожусь в состоянии, когда JVM не завершается. Странно то, что один поток прерывается, а другой нет. Я уверен, что делаю какую-то ошибку, но просто не могу понять, что.
РЕДАКТИРОВАТЬ:
Основной вопрос: почему только один поток генерирует исключение 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!!!");
}
}