Java: notify() vs. notifyAll()

Simply put, it depends on why your threads are waiting to be notified. Do you want to tell one of the waiting threads that something happened, or do you want to tell all of them at the same time?

In some cases, all waiting threads can take useful action once the wait finishes. An example would be a set of threads waiting for a certain task to finish; once the task has finished, all waiting threads can continue with their business. In such a case you would use notifyAll() to wake up all waiting threads at the same time.

Another case, for example mutually exclusive locking, only one of the waiting threads can do something useful after being notified (in this case acquire the lock). In such a case, you would rather use notify(). Properly implemented, you could use notifyAll() in this situation as well, but you would unnecessarily wake threads that can't do anything anyway.


notify vs notifyAll in Java

What is difference between notify and notifyAll method is one of the tricky Java question, which iseasy to answer but once Interviewer ask followup questions, you either gotconfused or not able to provide clear cut and to the point answers. Maindifference between notify and notifyAll is that notify methodwill only notify one Thread and notifyAll methodwill notify all Threads  which arewaiting on that monitor or lock. By the way this is something you have beenreading in all over places and to be frank, this statement despite being correct is not complete and its verydifficult to understand differencebetween notify vs notifyAll by just reading this statement. Lot of questionscomes in mind like

Which thread will be notified if I use notify()?
How do I know how many threads are waiting, so that I can use notifyAll() ?
How to call notify()?
What are these thread waiting for being notified etc.

Actually discussion of notify and notifyAll isincomplete without discussing wait method in Java and I had touched based onthis on my earlier article why wait and notify must be called fromsynchronized context. In order to get answer of those questions andunderstand difference between notify and notifyAll we will use a simple JavaThread example using wait and notify code :

Differencebetween notify and notifyAll in Java
Java provides two methods notify and notifyAll for wakingup threads waiting on some condition and you can use any of them but there issubtle difference between notify and notifyAll in Javawhich makes it one of the popular multi-threading interviewquestion in Java. When you call notify only oneof waiting thread will be woken and its not guaranteed which thread will bewoken, it depends upon Thread scheduler. While if you call notifyAll method, allthreads waiting on that lock will be woken up, but again all woken thread willfight for lock before executing remaining code and that's why wait is called onloop because if multiple threads are woken up, the thread which will get lockwill first execute and it may reset waiting condition, which will forcesubsequent threads to wait. So key differencebetween notify and notifyAll is that notify() will causeonly one thread to wake up while notifyAll method willmake all thread to wake up.


Whento use notify and notifyAll in Java
This is the follow-up question if you get pass the earlier one Difference between notifyAll andnotify in Java. If you understand notify vs notifyAll then youcan answer this by applying little common sense. You can use notify over notifyAll if allthread are waiting for same condition and only one Thread at a time can benefitfrom condition becoming true. In this case notify isoptimized call over notifyAll because waking up all of thembecause we know that only one thread will benefit and all other will wait again,so calling notifyAll method is just waste of cpu cycles. Though this looksquite reasonable there is still a caveat that unintended recipient swallowingcritical notification. by using notifyAll we ensurethat all recipient will get notify. Josh bloach has explained this in gooddetail in his book Effective Java , I highly recommend this book if you haven'tread them already. Another one you can try is Concurrency Practice in Java andJava Thread, which discusses wait and notify methods ingood details.

Example of notify and notifyAll method inJava

I have put together an example to show how all threads gets notified whenwe call notifyAll method in Java and just one Threadwill wake up when we call notify method in Java. In this examplethree threads will wait if boolean variable go is false, remember boolean go isa volatile variable, so that allthreads will see its updated value. Initially three threads WT1, WT2,WT3 will wait because variable go is false than onethread NT1 will make go true and notifyall threads by calling notifyAll method or notify just one threadby calling notify() method. In case of notify() call thereis no guarantee which thread will woke up and you can see it by running this Javaprogram multiple times. In case of notifyAll all threadwill woke up but they will compete for monitor or lock and the Thread whichwill get the lock first will finish its execution and resetting go to false which willforce other two threads still waiting. At the end of this program you will havetwo threads waiting and two threads including notification thread finished.Program will not terminate because other two threads are still waiting and theyare not daemon threads. Purpose ofthis notify and notifyAll example is to show you How to usethem and How notify and notifyAll method works in Java.

CodeExample of notify and notifyAll
Here is complete code example of How to use notify and notifyAll methodin Java. We have already explained when to use notify vs notifyAll method andthis example will clarify effect of calling notify and notifyAllmethod  in Java.

import java.util.logging.Level ;
import java.util.logging.Logger ;

/**
 * Java program to demonstrate How to use notify and notifyAll methodin Java and
 * How notify and notifyAllmethod notifies thread, which thread gets woke up etc.
 */
public classNotificationTest {

    private volatile booleango = false ;

    public static voidmain ( String args []) throwsInterruptedException {
        finalNotificationTest test = newNotificationTest () ;
     
        Runnable waitTask = new Runnable (){
     
            @ Override
            publicvoid
run (){
                try {
                    test. shouldGo () ;
                } catch ( InterruptedException ex ) {
                    Logger. getLogger (NotificationTest. class. getName ()).
                           log ( Level. SEVERE, null,ex ) ;
                }
                System. out. println ( Thread. currentThread () + " finishedExecution" ) ;
            }
        } ;
     
        Runnable notifyTask = new Runnable (){
     
            @ Override
            publicvoid
run (){
                test. go () ;
                System. out. println ( Thread. currentThread () + " finishedExecution" ) ;
            }
        } ;
     
        Thread t1 = newThread (waitTask, "WT1" ) ; //will wait
        Thread t2 = newThread (waitTask, "WT2" ) ; //will wait
        Thread t3 = newThread (waitTask, "WT3" ) ; //will wait
        Thread t4 = newThread (notifyTask, "NT1" ) ; //will notify
     
        //starting allwaiting thread

        t1. start () ;
        t2. start () ;
        t3. start () ;
     
        //pause to ensureall waiting thread started successfully
        Thread. sleep ( 200 ) ;
     
        //starting notifyingthread
        t4. start () ;
     
    }
    /*
     * wait and notify can only be called from synchronizedmethod or bock
     */

    private synchronized voidshouldGo () throwsInterruptedException {
        while (go != true ){
            System. out. println ( Thread. currentThread ()
                         + " is going to wait on this object" ) ;
            wait () ; //release lockand reacquires on wakeup
            System. out. println ( Thread. currentThread () + " is wokenup" ) ;
        }
        go = false ; //resettingcondition
    }
 
    /*
     * both shouldGo() and go() are locked on current objectreferenced by "this" keyword
     */

    private synchronized voidgo () {
        while (go == false ){
            System. out. println ( Thread. currentThread ()
            + "is going to notify all or one thread waiting on this object" ) ;

            go = true ; //makingcondition true for waiting thread
            //notify();// only one out of three waiting thread WT1, WT2,WT3 will woke up

            notifyAll () ; // all waitingthread  WT1, WT2,WT3 will woke up
        }
     
    }
 
}

Output in caseof using notify
Thread
[WT1, 5,main ] is going to wait on thisobject
Thread [WT3, 5,main ] is going to wait on thisobject
Thread [WT2, 5,main ] is going to wait on thisobject
Thread [NT1, 5,main ] is going to notify all or one thread waiting on this object
Thread [WT1, 5,main ] is woken up
Thread [NT1, 5,main ] finished Execution
Thread [WT1, 5,main ] finished Execution

Output in caseof calling notifyAll
Thread
[WT1, 5,main ] is going to wait on thisobject
Thread [WT3, 5,main ] is going to wait on thisobject
Thread [WT2, 5,main ] is going to wait on thisobject
Thread [NT1, 5,main ] is going to notify all or one thread waiting on this object
Thread [WT2, 5,main ] is woken up
Thread [NT1, 5,main ] finished Execution
Thread [WT3, 5,main ] is woken up
Thread [WT3, 5,main ] is going to wait on thisobject
Thread [WT2, 5,main ] finished Execution
Thread [WT1, 5,main ] is woken up
Thread [WT1, 5,main ] is going to wait on thisobject

I strongly recommend to run this Java program and understand outputproduce by it and try to understand it. Theory should complement practicalexample and if you see any inconsistency than let us know or try to rectify it.Along with deadlock, race condition and thread-safety,  inter thread communication is one of thefundamental of concurrent programming in Java.

Summary
In short here are answers of questions on notify and notifyAll we haveraised at the start of this tutorial:

Whichthread will be notified if I use notify()?
No guaranteed,  ThreadSchedulerwill pick a random thread from pool of waiting thread on that monitor. What is guaranteed is that only one Thread will be notified.

How do Iknow how many threads are waiting, so that I can use notifyAll() ?
Its depend upon your application logic, while coding you need to thinkwhether a piece of code can be run by multiple thread or not. A good example tounderstand inter-thread communication is implementing producer consumer pattern in Java.

How tocall notify()?
Wait() and notify() method can only be calledfrom synchronized method or block,you need to call notify method on object on which other threads are waiting.

What arethese thread waiting for being notified etc.
Thread wait on some condition e.g. in producer consumer problem, producerthread wait if shared queue is full and consumer thread wait if shared queue isempty. Since multiple thread are working with a shared resource theycommunicate with each other using wait and notify method.

That’s all on What is differencebetween notify and notifyAll method in Java and when to use notify vs notifyAll in Java. Now you should be able tounderstand and use notify and notifyAll method for inter-thread communicationin your Java program.

基于STM32设计的数字示波器全套资料(原理图、PCB图、源代码) 硬件平台: 主控器:STM32F103ZET6 64K RAM 512K ROM 屏幕器:SSD1963 分辨率:480*272 16位色 触摸屏:TSC2046 模拟电路: OP-TL084 OP-U741 SW-CD4051 CMP-LM311 PWR-LM7805 -LM7905 -MC34063 -AMS1117-3.3 DRT-ULN2003 6.继电器:信号继电器 7.电源:DC +12V 软件平台: 开发环境:RealView MDK-ARM uVision4.10 C编译器:ARMCC ASM编译器:ARMASM 连机器:ARMLINK 实时内核:UC/OS-II 2.9实时操作系统 GUI内核:uC/GUI 3.9图形用户接口 底层驱动:各个外设驱动程序 数字示波器功能: 波形发生器:使用STM32一路DA实现正弦,三角波,方波,白噪声输出。 任意一种波形幅值在0-3.3V任意可调、频率在一定范围任意可调、方波占空比可调。调节选项可以通过触摸屏完成设置。 SD卡存储: SD卡波形存储输出,能够对当前屏幕截屏,以JPG格式存储在SD卡上。能够存储1S内的波形数据,可以随时调用查看。 数据传输:用C#编写上位机,通过串口完成对下位机的控制。(1)实现STOP/RUN功能(2)输出波形电压、时间参数(3)控制截屏(4)控制波形发生器(5)控制完成FFT(6)波形的存储和显示 图形接口: UCGUI 水平扫速: 250 ns*、500ns、1μs、5 μs、10μs、50μs、500 μs、5ms 、50ms 垂直电压灵敏度:10mV/div, 20mV/div, 50mV/div, 0.1V/div, 0,2V/div, 0.5V/div, 1V/div,2V/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值