我使用ReentrantLock和Condition实现了Producer-Consumer程序。如果我首先启动Producer线程,我的实现运行没有任何错误。但是,如果我首先启动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();
}
}
}
答案 0 :(得分:0)
请参阅下面的类似示例,您应该使用await而不是wait并使用ReentrantLock返回的条件,您已经在做了。(请参阅ReentrantLock的Java文档):
package reentrant_prodcons;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Reentrant_ProdCons {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Queue<Integer> queue=new LinkedList<Integer>();
ReentrantLock lock=new ReentrantLock();
Condition con=lock.newCondition();
final int size = 5;
new Producer(lock, con, queue, size).start();
new Consumer(lock, con, queue).start();
}
}
class Producer extends Thread{
ReentrantLock lock;
Condition con;
Queue<Integer> queue;
int size;
public Producer(ReentrantLock lock, Condition con, Queue<Integer> queue, int size) {
this.lock = lock;
this.con = con;
this.queue = queue;
this.size=size;
}
public void run(){
for(int i=0;i<10;i++){
lock.lock();
while(queue.size()==size){
try {
con.await();
} catch (InterruptedException ex) {
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
}
}
queue.add(i);
System.out.println("Produced : "+i);
con.signal();
lock.unlock();
}
}
}
class Consumer extends Thread{
ReentrantLock lock;
Condition con;
Queue<Integer> queue;
public Consumer(ReentrantLock lock, Condition con, Queue<Integer> queue) {
this.lock = lock;
this.con = con;
this.queue = queue;
}
public void run(){
for(int i=0;i<10;i++){
lock.lock();
while(queue.size()<1){
try {
con.await();
} catch (InterruptedException ex) {
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println("Consumed : "+queue.remove());
con.signal();
lock.unlock();
}
}
}