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"); 
    } 

} 

Tôi đang nhận được java.lang.IllegalMonitorStateException trong phần wait(). Tôi muốn biết tôi đang làm gì sai ở đây. Bất kỳ ý tưởng ??Thực thi Java của Người tiêu dùng sản xuất ném java.lang.IllegalMonitorStateException

Ngoại lệ hoàn chỉnh mà tôi nhận được như sau.

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

Cung cấp ngăn xếp hoàn chỉnh, vui lòng – Jens

+1

Đã thêm vào câu hỏi. – station

Trả lời

2

Tôi nghĩ rằng tôi đã mã của bạn làm việc ...

Như đã trình bày bởi JB Nizet bạn phải gọi chờ đợi và thông báo trên các đối tượng queue. Tôi nghĩ rằng đối tượng đó phải được tuyên bố là static để được Nhà sản xuất và Người tiêu dùng chia sẻ.

Tôi đã bao gồm trong khi vòng lặp cho mã tiếp tục chạy cho đến cuối thời gian.

Ngoài ra, thêm một notify là cần thiết trước khi nhà sản xuất và người tiêu dùng đầu tiên wait

Đây là mã của bạn với những thay đổi bao gồm:

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

Phần người tiêu dùng không hoạt động. Chủ đề người tiêu dùng bắt đầu ban đầu và đang chờ đợi. Các nhà sản xuất sản xuất tất cả các yếu tố nhưng sau đó người tiêu dùng không nhận. – station

+0

Bạn có chắc chắn rằng bạn đã sao chép tất cả các thay đổi? Tôi vừa chạy lại nó và nó hoạt động – RubioRic

+1

My Bad. Tôi đã thử nó một lần nữa nó hoạt động, Cảm ơn – station

6

Bạn đang gọi điện thoại wait(), tương đương với this.wait(), nhưng bạn không giữ màn hình của this. Bạn đang giữ màn hình trên queue. Vì vậy, nó phải là queue.wait(). (tương tự cho notify()).

+0

Tôi đang thực hiện một số thử nghiệm ... Thành viên 'xếp hàng' không phải là tĩnh để được chia sẻ bởi nhà sản xuất và người tiêu dùng? – RubioRic

+0

Điều này phải là câu trả lời được chấp nhận ... –

3

Check-out Javadoc cho IllegalMonitorStateException

https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalMonitorStateException.html

Trường hợp ngoại lệ được ném khi bạn cố gắng wait() (hoặc notify()) trên một đối tượng trong đó quí vị không có màn hình; Bạn đã đồng bộ hóa trên hàng đợi nhưng đã cố gắng wait() trên this, không phải là hàng đợi, thay vì runnable. Thay đổi wait() thành queue.wait()notify() đến queue.notify() sẽ hoạt động.

0

Một thread có thể gọi thông báo() hoặc wait() chỉ trên một đối tượng mà nó đã có khóa. Trong chuỗi chương trình của bạn có khóa trên đối tượng hàng đợi và sau đó thread của bạn đang chờ cuộc gọi này.

Các vấn đề liên quan