java - 是否可以在Java中等待特定锁的线程上调用notifyAll()?

标签 java multithreading

我很好奇是否有一种方法可以通知正在等待特定锁的线程。我收到异常,据我了解,这是因为我在不同方法的同步代码段中调用了notifyAll()。 据我了解,notifyAll() 正在唤醒正在等待所有锁的所有线程。这是代码

public class Buffer {

    private static Buffer instance = null;
    private boolean full = false;
    private boolean empty = true;

    private Object lock1 = new Object();
    private Object lock2 = new Object();

    private char[] arr;
    private int i;

    private Buffer(){
        arr = new char[26];
        i = 0;
    }

    public static synchronized Buffer getInstance(){
        if(instance == null){
            instance = new Buffer();
        }
        return instance;
    }

    public void put(char c){

        synchronized(lock1){
            while(full){
                try{
                    wait();
                }catch(Exception e){}
            }

            arr[i++] = c;
            empty = false;
            if(i == 25){
                full = true;
                notifyAll();
            }else{
                full = false;
            }
        }
    }

    public char get(){
        synchronized(lock2){
            while(empty){
                try{
                    wait();
                }catch(Exception e){}
            }

            if(--i == 0){
                empty = true;
            }else{
                notifyAll();
            }
            full = false;
            return arr[i];
        }
    }

    public boolean isEmpty(){
        return i == 0;
    }
} 

我得到异常

java.lang.IllegalMonitorStateException
    at java.lang.Object.notifyAll(Native Method)
    at Producer_consumer.Buffer.get(Buffer.java:58)
    at Producer_consumer.Consumer.run(Consumer.java:14)
    at java.lang.Thread.run(Thread.java:745)

或者如果不可能..如何解决这种情况?

最佳答案

notifyAll 唤醒正在等待特定锁(您正在调用 notifyAll 的锁)的所有线程。但是要调用 waitnotify/notifyAll 您需要在该监视器上持有同步锁。

如果在调用 waitnotify 时没有在监视器上持有同步锁,则会收到 IllegalMonitorStateException

因此,在您的示例中,您处于 synchronized(lock1){...} 内,您需要调用 lock1.wait()lock1 .notifyAll()lock2 上也类似。

您现在在代码中执行的操作是在 this 对象上调用 wait。 Java中的每个对象都有一个监视器,你可以在它上面进行同步、等待和通知。因此,您需要非常小心执行这些操作的对象。

如果您想通知不同的监视器,您需要先在其上进行同步。

关于java - 是否可以在Java中等待特定锁的线程上调用notifyAll()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30158829/

相关文章:

java - 不重复随机数数组

java - Libgdx,使用 Shader 的 Alpha 文本不起作用

C++ freeRTOS 任务,非静态成员函数的无效使用

java - 为什么servlet的init()方法运行在不同的线程中?

java - WebCrawler stop方法逻辑【并发实践7.2.5】

java - liferay "Failed to load resource: net::ERR_CONTENT_LENGTH_MISMATCH"用于图像(即使是来自 DLFileEntry 对象的小图像)

java - 在构建 Android 应用程序之前,将 jar 从其他目录拉到 libs 文件夹

c++ - std::thread 和 std::cin 在 opengl 应用程序中的输入

c - 为什么我不能在线程函数内返回值?

java - 在 JPA 中获取单列值