6
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。我想知道我在这里做错了什么。有任何想法吗??Java实现生产者消费者的抛出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) 
+2

提供完整的堆栈跟踪请 – Jens

+1

在问题中添加。 – station

回答

2

我认为我得到了你的代码的工作...

正如JB Nizet说你必须调用wait和notify的queue对象。 我认为这样的对象必须声明为static才能被Producer和Consumer共享。

我已经包含循环代码,以便继续运行直到时间结束。

而且,额外的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"); 
    } 

} 

enter image description here

+0

消费者部分不工作。消费者线程最初开始并正在等待。制片人制作了所有元素,但消费者并没有选择。 – station

+0

您确定您已经复制了所有更改吗?我刚刚运行它,它的工作 – RubioRic

+1

我的坏。我再次尝试它的工作,谢谢 – station

6

你打电话wait(),这相当于this.wait(),但你不能拿着this显示器。你正在拿着显示器queue。所以它应该是queue.wait()。 (与notify()相同)。

+0

我正在做一些测试......成员'队列'不必是静态的才能被生产者和消费者共享? – RubioRic

+0

这应该是被接受的答案... –

0

一个线程可以调用notify()或仅在其已获取锁定的对象上等待()。在你的程序中,线程锁定了队列对象,然后你的线程正在等待这个。