您的位置:

Java中的notify和notifyAll方法有什么区别和使用场景?

Java中的notify和notifyAll方法是用于多线程编程中的线程间通信机制。在多线程编程中,多个线程可能需要对共享的资源进行访问,为了保证多个线程之间的协作和同步,Java提供了很多机制,其中wait、notify和notifyAll方法就是其中的一种。

一、notify和notifyAll方法的作用与区别

notify和notifyAll方法都是用于在同步代码块中唤醒等待线程的方法,它们的作用都是唤醒在调用对象上等待的线程。具体来讲,当有其他线程调用了该对象的notify()或notifyAll()方法时,处于该对象等待池中的线程就可以被唤醒,从而继续执行。

notify方法的作用是随机选取等待在该对象上的某一个线程进行唤醒,而notifyAll方法则是唤醒该对象所有等待池中的线程,并让它们进入锁竞争池,争夺执行权。简单来说,notify方法是唤醒单个线程,notifyAll方法是唤醒所有等待线程。

二、notify和notifyAll方法的使用场景

由于notify方法只能唤醒某一个等待线程,无法来实现群体唤醒,因此在某些情况下,使用notify方法可能会造成线程饥饿,即有些线程一直得不到执行。

而notifyAll方法则没有这个问题,它能够唤醒所有等待线程,使得它们都有机会来竞争执行权,从而避免了线程饥饿的问题。因此,当共享资源被多个线程所使用,并且线程间的协作非常重要时,通常使用notifyAll方法。

三、notify和notifyAll方法的示例代码

下面是notify和notifyAll方法的示例代码,分别使用两者来实现线程同步和协作。

class SharedObject{
    private boolean flag = false;
    public synchronized void doWait(){
        while(!flag){
            try{
                wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        flag = false;
        notify();
    }
    public synchronized void doNotify(){
        while(flag){
            try{
                wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        flag = true;
        notify();
    }
}

在上面的代码中,flag用于标记是否有资源可用,如果flag为true,则表示资源可用,若为false,则表示资源不可用。doWait()方法在等待资源变为可用,当flag为false时,调用wait()方法进行等待,直到doNotify()方法唤醒该线程。当资源可用时,flag会被设置为false,并通过notify()方法通知其他线程进行竞争。doNotify()方法则是在资源可用时,将flag设置为true,并调用notify()方法唤醒其他线程进行竞争。