Java 生产者消费者的实施抛出 java.lang.IllegalMonitorStateException
Java implementation of Producer Consumer throws java.lang.IllegalMonitorStateException
import java.util.LinkedList;
import java.util.Queue;
class Producer extends PubSub implements Runnable{
@Override
public void run() {
synchronized(queue){
if (queue.size() == 99){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.add(2);
try{
Thread.sleep(1000);
}
catch (InterruptedException e){
e.printStackTrace();
}
notify();
}
}
}
class Consumer extends PubSub implements Runnable{
@Override
public void run() {
synchronized(queue){
if(queue.isEmpty()){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(queue.poll());
}
}
}
public class PubSub {
static Integer QUEUE_SIZE = 100;
Queue<Integer> queue = new LinkedList<Integer>();
public static void main(String[] args) {
Producer producer = new Producer();
Consumer consumer = new Consumer();
Thread producerThread = new Thread(producer);
Thread consumerThread = new Thread(consumer);
producerThread.start();
consumerThread.start();
System.out.println("Started both the threads");
}
}
我在 wait()
部分得到一个 java.lang.IllegalMonitorStateException
。我想知道我在这里做错了什么。有什么想法吗??
我得到的完整异常如下。
Exception in thread "Thread-1" Started both the threads
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at Consumer.run(PubSub.java:36)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at Producer.run(PubSub.java:23)
at java.lang.Thread.run(Thread.java:745)
你呼叫的是wait()
,相当于this.wait()
,但你并没有持有this
的监听。您在 queue
上拿着显示器。所以应该是queue.wait()
。 (与 notify()
相同)。
查看 Javadoc 以了解 IllegalMonitorStateException
https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalMonitorStateException.html
当您尝试 wait()
(或 notify()
)您未持有监视器的对象时抛出异常;您已在队列上同步,但试图在 this
上 wait()
,这不是队列,而是可运行的。
将 wait()
更改为 queue.wait()
并将 notify()
更改为 queue.notify()
应该有效。
我想我让你的代码工作了...
正如 JB Nizet 所述,您必须在 queue
对象上调用等待和通知。
我认为必须声明这样的对象 static
才能由生产者和消费者共享。
我为代码添加了 while 循环以继续 运行 直到时间结束。
此外,在生产者和消费者之前还需要一个额外的notify
wait
这是包含更改的代码:
import java.util.LinkedList;
import java.util.Queue;
class Producer extends PubSub implements Runnable{
@Override
public void run() {
int index = 0;
while (true) {
synchronized(queue){
while (queue.size() == QUEUE_SIZE){
try {
System.out.println("Producer waits");
queue.notify();
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produce element " + (++index));
queue.add(2);
queue.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
}
class Consumer extends PubSub implements Runnable{
@Override
public void run() {
while (true) {
synchronized(queue) {
while (queue.isEmpty()){
try {
System.out.println("Consumer waits");
queue.notify();
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consume element " + queue.poll());
queue.notify();
}
}
}
}
public class PubSub {
static Integer QUEUE_SIZE = 100;
static Queue<Integer> queue = new LinkedList<Integer>();
public static void main(String[] args) {
Producer producer = new Producer();
Consumer consumer = new Consumer();
Thread producerThread = new Thread(producer);
Thread consumerThread = new Thread(consumer);
producerThread.start();
consumerThread.start();
System.out.println("Started both the threads");
}
}
线程只能在它已经获得锁的对象上调用 notify() 或 wait() 。在您的程序中,线程锁定了队列对象,然后您的线程正在调用等待。
import java.util.LinkedList;
import java.util.Queue;
class Producer extends PubSub implements Runnable{
@Override
public void run() {
synchronized(queue){
if (queue.size() == 99){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.add(2);
try{
Thread.sleep(1000);
}
catch (InterruptedException e){
e.printStackTrace();
}
notify();
}
}
}
class Consumer extends PubSub implements Runnable{
@Override
public void run() {
synchronized(queue){
if(queue.isEmpty()){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(queue.poll());
}
}
}
public class PubSub {
static Integer QUEUE_SIZE = 100;
Queue<Integer> queue = new LinkedList<Integer>();
public static void main(String[] args) {
Producer producer = new Producer();
Consumer consumer = new Consumer();
Thread producerThread = new Thread(producer);
Thread consumerThread = new Thread(consumer);
producerThread.start();
consumerThread.start();
System.out.println("Started both the threads");
}
}
我在 wait()
部分得到一个 java.lang.IllegalMonitorStateException
。我想知道我在这里做错了什么。有什么想法吗??
我得到的完整异常如下。
Exception in thread "Thread-1" Started both the threads
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at Consumer.run(PubSub.java:36)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at Producer.run(PubSub.java:23)
at java.lang.Thread.run(Thread.java:745)
你呼叫的是wait()
,相当于this.wait()
,但你并没有持有this
的监听。您在 queue
上拿着显示器。所以应该是queue.wait()
。 (与 notify()
相同)。
查看 Javadoc 以了解 IllegalMonitorStateException
https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalMonitorStateException.html
当您尝试 wait()
(或 notify()
)您未持有监视器的对象时抛出异常;您已在队列上同步,但试图在 this
上 wait()
,这不是队列,而是可运行的。
将 wait()
更改为 queue.wait()
并将 notify()
更改为 queue.notify()
应该有效。
我想我让你的代码工作了...
正如 JB Nizet 所述,您必须在 queue
对象上调用等待和通知。
我认为必须声明这样的对象 static
才能由生产者和消费者共享。
我为代码添加了 while 循环以继续 运行 直到时间结束。
此外,在生产者和消费者之前还需要一个额外的notify
wait
这是包含更改的代码:
import java.util.LinkedList;
import java.util.Queue;
class Producer extends PubSub implements Runnable{
@Override
public void run() {
int index = 0;
while (true) {
synchronized(queue){
while (queue.size() == QUEUE_SIZE){
try {
System.out.println("Producer waits");
queue.notify();
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produce element " + (++index));
queue.add(2);
queue.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
}
class Consumer extends PubSub implements Runnable{
@Override
public void run() {
while (true) {
synchronized(queue) {
while (queue.isEmpty()){
try {
System.out.println("Consumer waits");
queue.notify();
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consume element " + queue.poll());
queue.notify();
}
}
}
}
public class PubSub {
static Integer QUEUE_SIZE = 100;
static Queue<Integer> queue = new LinkedList<Integer>();
public static void main(String[] args) {
Producer producer = new Producer();
Consumer consumer = new Consumer();
Thread producerThread = new Thread(producer);
Thread consumerThread = new Thread(consumer);
producerThread.start();
consumerThread.start();
System.out.println("Started both the threads");
}
}
线程只能在它已经获得锁的对象上调用 notify() 或 wait() 。在您的程序中,线程锁定了队列对象,然后您的线程正在调用等待。