Я реализовал программу Продюсер-Потребитель, используя ReentrantLock и Condition. Моя реализация выполняется без каких-либо ошибок, если я сначала запустил нить производителя. Но если я сначала запускаю поток Consumer, я получаю исключение IllegalMonitorStateException. Пожалуйста, укажите, что не так с моей программой.Проблема с производителем-потребителем с использованием блокировки и состояния
Вот моя реализация.
public class ProducerConsumerReentrantLock {
public static void main(String[] args) throws InterruptedException {
List<Integer> list = new ArrayList<Integer>(10);
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
int limit=10;
ProductionTaskReentrantLock produce = new ProductionTaskReentrantLock(lock, condition, limit, list);
ConsumptionTaskReentrantLock consume = new ConsumptionTaskReentrantLock(lock, condition, limit, list);
Thread productionWorker = new Thread(produce,"Producer");
Thread consumptionWorker = new Thread(consume,"Consumer");
consumptionWorker.start();
productionWorker.start();
// consumptionWorker.start();
productionWorker.join();
consumptionWorker.join();
}
}
.
class ProductionTaskReentrantLock implements Runnable{
List<Integer> list = null;
ReentrantLock lock;
Condition condition;
int limit;
public ProductionTaskReentrantLock(ReentrantLock lock, Condition condition, int limit, List<Integer> list) {
super();
this.lock = lock;
this.condition = condition;
this.limit = limit;
this.list = list;
}
@Override
public void run() {
lock.lock();
try{
for (int i = 0; i < 10 ; i++) {
while(list.size()==limit){
try {
System.out.println("List is full");
condition.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced "+i);
list.add(i);
System.out.println(list);
condition.signalAll();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
lock.unlock();
}
}
}
.
class ConsumptionTaskReentrantLock implements Runnable{
List<Integer> list = null;
ReentrantLock lock;
Condition condition;
int limit;
public ConsumptionTaskReentrantLock(ReentrantLock lock, Condition condition, int limit, List<Integer> list) {
super();
this.lock = lock;
this.condition = condition;
this.limit = limit;
this.list = list;
}
@Override
public void run() {
lock.lock();
try{
for (int i = 0; i < 10 ; i++) {
while(list.isEmpty()){
try {
System.out.println("List is empty");
condition.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed "+list.remove(0));
System.out.println(list);
condition.signalAll();
}
} finally {
lock.unlock();
}
}
}
IllegalMonitorStateException - Брошенный в. указывают, что поток попытался подождать на мониторе объекта или уведомить другие потоки, ожидающие монитора объекта, не владея указанным монитором. – mcraen
Я не знаю достаточно о потоке Java, чтобы быстро выбрать вашу ошибку, но это довольно описательное сообщение об ошибке – mcraen
Можете ли вы попробовать использовать condition.await() вместо ожидания и посмотреть, разрешит ли это это? – Kamal