• Java Thread wait, notify and notifyAll Example


    Java Thread wait, notify and notifyAll Example 

      Java线程中的使用的wait,notify和nitifyAll方法示例.

    The Object class in java contains three final methods that allows threads to communicate about the lock status of a resource. These methods
    are wait(), notify() and notifyAll().

      方法:wait,notify和notifyAll都是Object类中的方法而且还是final类型的,不允许重载。这三个方法主要是为了线程间通信使用,通信采用的机制是锁机制。

    The current thread which invokes these methods on any object should have the object monitor else it throws java.lang.IllegalMonitorStateException exception.

      当前线程调用这些方法需要try,catch,因为他会抛异常。

    wait

    Object wait methods has three variance, one which waits indefinitely for any other thread to call notify or notifyAll method on the object to wake up the current thread. Other two variances puts the current thread in wait for specific amount of time before they wake up.

      线程wait有三种含义,一种是wait之后等到其他线程去唤醒,可以使用notify或者是notifyaAll方法,另一种是自己指定wait的时间,时间到了自己唤醒自己。

    notify

    notify method wakes up only one thread waiting on the object and that thread starts execution. So if there are multiple threads waiting for an object, this method will wake up only one of them. The choice of the thread to wake depends on the OS implementation of thread management.

      notify方法一次只能唤醒一个线程,然后唤醒线程得以执行。因此在多线程中这种方式一次只能唤醒一个,具体唤醒那个依赖于OS线程管理的实现。

    notifyAll

    notifyAll method wakes up all the threads waiting on the object, although which one will process first depends on the OS implementation.

      方法notifyAll唤醒所有使用这个对象锁的线程,只是先后顺序依赖于OS的实现。

    These methods can be used to implement producer consumer problem where consumer threads are waiting for the objects in Queue and producer threads put object in queue and notify the waiting threads.

      一般情况这个方法使用在生产者和消费者的问题上,消费线程等待消费队列中的商品,生产者则生产这些商品最后丢带队列中,以供消费者使用。

    Let’s see an example where multiple threads work on the same object and we use wait, notify and notifyAll methods

      一起看个关于多线程的例子,使用同一个对象去wait,notify和notifyAll方法。

    Message.java

     1 package com.journaldev.concurrency;
     2  
     3 public class Message {
     4     private String msg;
     5      
     6     public Message(String str){
     7         this.msg=str;
     8     }
     9  
    10     public String getMsg() {
    11         return msg;
    12     }
    13  
    14     public void setMsg(String str) {
    15         this.msg=str;
    16     }
    17  
    18 }

    Waiter

    A class that will wait for other threads to invoke notify methods to complete it’s processing. Notice that Waiter thread is owning monitor on Message object using synchronized block.

      这个类则等待其他线程去调用notify方法去完成所有代码的执行。注意waiter线程(等待被唤醒的线程)自己使用了messge对象作为synchronized的锁。
    waiter.java
     1 package com.journaldev.concurrency;
     2  
     3 public class Waiter implements Runnable{
     4      
     5     private Message msg;
     6      
     7     public Waiter(Message m){
     8         this.msg=m;
     9     }
    10  
    11     @Override
    12     public void run() {
    13         String name = Thread.currentThread().getName();
    14         synchronized (msg) {
    15             try{
    16                 System.out.println(name+" waiting to get notified at time:"+System.currentTimeMillis());
    17                 msg.wait();
    18             }catch(InterruptedException e){
    19                 e.printStackTrace();
    20             }
    21             System.out.println(name+" waiter thread got notified at time:"+System.currentTimeMillis());
    22             //process the message now
    23             System.out.println(name+" processed: "+msg.getMsg());
    24         }
    25     }
    26  
    27 }

    Notifier

    A class that will process on Message object and then invoke notify method to wake up threads waiting for Message object. Notice that synchronized block is used to own the monitor of Message object.
      这个类使用message对象去调用notify方法,然后唤醒使用message对象wait的线程,注意,这里同样使用了Message对象去作为sysnchronized的锁。

    Notifier.java

     1 package com.journaldev.concurrency;
     2  
     3 public class Notifier implements Runnable {
     4  
     5     private Message msg;
     6      
     7     public Notifier(Message msg) {
     8         this.msg = msg;
     9     }
    10  
    11     @Override
    12     public void run() {
    13         String name = Thread.currentThread().getName();
    14         System.out.println(name+" started");
    15         try {
    16             Thread.sleep(1000);
    17             synchronized (msg) {
    18                 msg.setMsg(name+" Notifier work done");
    19                 msg.notify();
    20                 // msg.notifyAll();
    21             }
    22         } catch (InterruptedException e) {
    23             e.printStackTrace();
    24         }
    25          
    26     }
    27  
    28 }

    WaitNotifyTest

    Test class that will create multiple threads of Waiter and Notifier and start them.

      测试上述内容在多线程中调用waiter和notifier实现等待和唤醒。

     1 package com.journaldev.concurrency;
     2  
     3 public class WaitNotifyTest {
     4  
     5     public static void main(String[] args) {
     6         Message msg = new Message("process it");
     7         Waiter waiter = new Waiter(msg);
     8         new Thread(waiter,"waiter").start();
     9          
    10         Waiter waiter1 = new Waiter(msg);
    11         new Thread(waiter1, "waiter1").start();
    12          
    13         Notifier notifier = new Notifier(msg);
    14         new Thread(notifier, "notifier").start();
    15         System.out.println("All the threads are started");
    16     }
    17  
    18 }
    When we will invoke the above program, we will see below output but program will not complete because there are two threads waiting on Message object and notify() method has wake up only one of them, the other thread is still waiting to get notified.
     
      当我们执行了上述程序,我们将看到如下输出,代码并没有执行完,而是只执行了一部分,至少可以说是一个县城没有执行结束,很明显两个等待被唤醒的线程使用了同一个message对象,当我们使用该对象就行notify的时候只是唤醒了其中一个,另一个一直在等待唤醒状态。
     
    Notify():
    1 waiter waiting to get notified at time:1356318734009
    2 waiter1 waiting to get notified at time:1356318734010
    3 All the threads are started
    4 notifier started
    5 waiter waiter thread got notified at time:1356318735011
    6 waiter processed: notifier Notifier work done
    If we comment the notify() call and uncomment the notifyAll() call in Notifier class, below will be the output produced.
      如果我们想替换notify方法为nofityAll那在Notify类中,那么就输出是所有的线程都会执行完成。
    NotifyAll():
    1 waiter waiting to get notified at time:1356318917118
    2 waiter1 waiting to get notified at time:1356318917118
    3 All the threads are started
    4 notifier started
    5 waiter1 waiter thread got notified at time:1356318918120
    6 waiter1 processed: notifier Notifier work done
    7 waiter waiter thread got notified at time:1356318918120
    8 waiter processed: notifier Notifier work done

    Since notifyAll() method wake up both the Waiter threads and program completes and terminates after execution.

      这就是Notify方法唤醒所有使用message对象wait的线程的程序执行结果,程序执行都是彻底的,没有出现wait 的情况。
     
    翻译不当之处,愿君谅解!!!
     
     
     
     
  • 相关阅读:
    团队项目心得(一)
    《effective c++》读书笔记(上)
    前端进度报告(2018.5.17)
    DeltaFish 校园物资共享平台 第五次小组会议
    项目--用户调研
    DeltaFish 校园物资共享平台 第四次小组会议
    DeltaFish 校园物资共享平台 第三次小组会议
    创建校园二手交易及资源共享平台的问卷调查
    项目平台统一(前后端IDE、代码风格)
    DeltaFish 校园物资共享平台 第二次小组会议
  • 原文地址:https://www.cnblogs.com/liemng/p/5315104.html
Copyright © 2020-2023  润新知