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()方法唤醒其他线程进行竞争。