为什么此代码会导致非法监视器状态异常? [英] Why does this code result in illegalMonitorState exception?
问题描述
下面的代码试图将随机值插入循环队列并将其删除.但是,存在一些同步问题.我知道我可以使用更高级别的例程,而我将在生产代码中使用该例程,但是我很好奇为什么这行不通?我在这里想念什么?
The code below is trying to insert a random value into a circular queue and remove it. However, there are some synchronization issues. I know I can use higher level routines and I'm going to do that for production code but I was curious why this does not work ? What am I missing here ?
public class CircularQueue {
int count;
int rear;
int front;
Object lock = new Object();
int size;
int[] array;
CircularQueue(int size)
{
this.size= size;
array = new int[size];
}
void enqueue(int number) throws InterruptedException
{
if(isFull())
lock.wait();
synchronized(lock)
{
array[rear] = number;
System.out.println("Rear is:"+ rear+ "value is:"+number+"Size is:"+size);
rear = (rear+1)%size;
count++;
}
lock.notify();
}
void dequeue() throws InterruptedException
{
if(isEmpty())
lock.wait();
synchronized(lock)
{
int retVal = 0;
retVal = array[front];
System.out.println("Front is:"+ front+ "value is:"+retVal);
front = (front+1)%size;
count--;
}
lock.notify();
}
boolean isFull()
{
if(count == size)
{
return true;
}
else
return false;
}
boolean isEmpty()
{
return count == 0;
}
}
//测试班
import java.util.Random;
public class App {
public static void main(String[] args) throws InterruptedException
{
final Random random = new Random();
final CircularQueue circularQueue = new CircularQueue(10);
Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
try {
circularQueue.enqueue(random.nextInt(100));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
try {
circularQueue.dequeue();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
推荐答案
因为必须从同步块中调用java.lang.Object#wait
,java.lang.Object#notify
,java.lang.Object#notifyAll
.
Because java.lang.Object#wait
, java.lang.Object#notify
, java.lang.Object#notifyAll
must be called from synchronized block.
作为解决方案(需要检查),您应该将条件放入同步块中:
As a solution(need to check) you should put your conditions inside synchronized blocks:
void enqueue(int number) throws InterruptedException
{
synchronized(lock)
{
if(isFull())
lock.wait();
array[rear] = number;
System.out.println("Rear is:"+ rear+ "value is:"+number+"Size is:"+size);
rear = (rear+1)%size;
count++;
lock.notify();
}
}
void dequeue() throws InterruptedException
{
synchronized(lock)
{
if(isEmpty())
lock.wait();
int retVal = 0;
retVal = array[front];
System.out.println("Front is:"+ front+ "value is:"+retVal);
front = (front+1)%size;
count--;
lock.notify();
}
}
这篇关于为什么此代码会导致非法监视器状态异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!