【发布时间】:2020-05-11 09:37:43
【问题描述】:
我有一段代码在调用 notifyAll 时给出 IllegalMonitorException。在 enQueue() 时,线程添加数据并抛出非法监视器异常。
BlockingQueue.class:
public class BlockingQueue {
private Queue<Integer> queue = new LinkedList<>();
private int maxCount;
private Lock lock = new ReentrantLock();
BlockingQueue(int maxCount){
this.maxCount=maxCount;
}
public void enQueue(int d) throws InterruptedException {
lock.lock();
if(queue.size() >= maxCount){
System.out.println("going to wait enqueu "+Thread.currentThread().getName() +" size "+queue.size());
lock.wait();
}
System.out.println(" Adding "+d);
queue.add(d);
lock.notify();
lock.unlock();
}
public Integer deQueue() throws InterruptedException {
lock.lock();
if(queue.size()==0){
System.out.println("going to wait dequeue "+Thread.currentThread().getName()+" size "+queue.size());
lock.wait();
}
int data = queue.remove();
lock.notify();
lock.unlock();
return data;
}}
主类:
public class Main {
public static void main(String args[]){
BlockingQueue queue=new BlockingQueue(10);
Producer p = new Producer(queue);
Consumer c = new Consumer(queue);
Thread t1=new Thread(c,"Consumer");
Thread t2=new Thread(p, "producer");
t1.start();
t2.start();
}}
生产者.类:
public class Producer implements Runnable {
private BlockingQueue q;
Producer(BlockingQueue qu){
this.q=qu;
}
public Integer generateWork() throws InterruptedException {
return new Random().nextInt(100 );
}
@Override
public void run() {
for(int i =0; i<100; i++){
try {
Thread.sleep(100);
q.enQueue(generateWork());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}}
消费者类:
public class Consumer implements Runnable {
private BlockingQueue queue;
Consumer(BlockingQueue q){
this.queue=q;
}
public void consume(int data){
System.out.println(" consume "+data);
}
@Override
public void run() {
for(int i=0; i < 100; i++){
try {
Thread.sleep(1000);
consume(queue.deQueue());
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}}
输出:
添加 94
线程“生产者”java.lang.IllegalMonitorStateException 中的异常
at java.lang.Object.notify(Native Method)
at BlockingQueue.enQueue(BlockingQueue.java:23)
at Producer.run(Producer.java:20)
at java.lang.Thread.run(Thread.java:748)
【问题讨论】:
-
你能发布完整的代码来重现这个问题吗?
-
嘿..我已经更新了代码。我不想使用条件。 ://
-
如果您使用的是
Lock,那么您必须使用Condition。但是你为什么犹豫使用Condition? -
@Slaw
Condition和Lock不是强制使用的,但它是一个很棒的组合。 -
@YogeshBadke 如果您想正确使用 API。虽然您的答案可能有效,但应该或者使用
synchronized和Object的等待/通知或Lock和Condition的等待/信号。使用synchronized (lock),其中lock是java.util.concurrent.locks.Lock的一个实例,是代码异味。
标签: java multithreading thread-safety reentrantlock illegalmonitorstateexcep