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

 package com.journaldev.concurrency;

 public class Message {
private String msg; public Message(String str){
this.msg=str;
} public String getMsg() {
return msg;
} public void setMsg(String str) {
this.msg=str;
} }

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
 package com.journaldev.concurrency;

 public class Waiter implements Runnable{

     private Message msg;

     public Waiter(Message m){
this.msg=m;
} @Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (msg) {
try{
System.out.println(name+" waiting to get notified at time:"+System.currentTimeMillis());
msg.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(name+" waiter thread got notified at time:"+System.currentTimeMillis());
//process the message now
System.out.println(name+" processed: "+msg.getMsg());
}
} }

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

 package com.journaldev.concurrency;

 public class Notifier implements Runnable {

     private Message msg;

     public Notifier(Message msg) {
this.msg = msg;
} @Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name+" started");
try {
Thread.sleep(1000);
synchronized (msg) {
msg.setMsg(name+" Notifier work done");
msg.notify();
// msg.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} } }

WaitNotifyTest

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

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

 package com.journaldev.concurrency;

 public class WaitNotifyTest {

     public static void main(String[] args) {
Message msg = new Message("process it");
Waiter waiter = new Waiter(msg);
new Thread(waiter,"waiter").start(); Waiter waiter1 = new Waiter(msg);
new Thread(waiter1, "waiter1").start(); Notifier notifier = new Notifier(msg);
new Thread(notifier, "notifier").start();
System.out.println("All the threads are started");
} }
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():
 waiter waiting to get notified at time:1356318734009
waiter1 waiting to get notified at time:1356318734010
All the threads are started
notifier started
waiter waiter thread got notified at time:1356318735011
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():
 waiter waiting to get notified at time:1356318917118
waiter1 waiting to get notified at time:1356318917118
All the threads are started
notifier started
waiter1 waiter thread got notified at time:1356318918120
waiter1 processed: notifier Notifier work done
waiter waiter thread got notified at time:1356318918120
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 的情况。
 
翻译不当之处,愿君谅解!!!
 
 
 
 

Java Thread wait, notify and notifyAll Example的更多相关文章

  1. [译]Java Thread wait, notify和notifyAll示例

    Java Thread wait, notify和notifyAll示例 Java上的Object类定义了三个final方法用于不同线程间关于某资源上的锁状态交互,这三个方法是:wait(), not ...

  2. java wait()和notify()、notifyAll()

    图见<JAVA并发编程的艺术>P98-101 这三个方法都是java.lang.Object的方法,用于协调多个线程对共享数据的存取,必须在synchronized语句块中使用!这三个方法 ...

  3. Java的wait(), notify()和notifyAll()使用小结

    wait(),notify()和notifyAll()都是java.lang.Object的方法: wait(): Causes the current thread to wait until an ...

  4. Java多线程 wait, notify 和 notifyAll

    Java的Object类 public class Object { public final native void notify(); public final native void notif ...

  5. Java的wait(), notify()和notifyAll()使用心得(转)

    本篇文章是对java的 wait(),notify(),notifyAll()进行了详细的分析介绍,需要的朋友参考下wait(),notify()和notifyAll()都是java.lang.Obj ...

  6. java中的notify和notifyAll有什么区别?

    先说两个概念:锁池和等待池 锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入 ...

  7. 精通java并发-wait,notify和notifyAll的总结(含案例)

    目前CSDN,博客园,简书同步发表中,更多精彩欢迎访问我的gitee pages wait,notify和notifyAll 总结 在调用wait方法时,线程必须要持有被调用对象的锁,当调用wait方 ...

  8. Java 中 wait, notify 和 notifyAll的正确使用 – 以生产者消费者模型为例

    如何使用Wait 尽管关于wait和notify的概念很基础,它们也都是Object类的函数,但用它们来写代码却并不简单.如果你在面试中让应聘者来手写代码,用wait和notify解决生产者消费者问题 ...

  9. Java 多线程学习笔记:wait、notify、notifyAll的阻塞和恢复

    前言:昨天尝试用Java自行实现生产者消费者问题(Producer-Consumer Problem),在coding时,使用到了Condition的await和signalAll方法,然后顺便想起了 ...

随机推荐

  1. 从零开始山寨Caffe·贰:主存模型

    你左手是内存,右手是显存,内存可以打死显存,显存也可以打死内存. —— 请协调好你的主存 从硬件说起 物理之觞 大部分Caffe源码解读都喜欢跳过这部分,我不知道他们是什么心态,因为这恰恰是最重要的一 ...

  2. 洛谷 P2737 [USACO4.1]麦香牛块Beef McNuggets Label:一点点数论 && 背包

    题目描述 农夫布朗的奶牛们正在进行斗争,因为它们听说麦当劳正在考虑引进一种新产品:麦香牛块.奶牛们正在想尽一切办法让这种可怕的设想泡汤.奶牛们进行斗争的策略之一是“劣质的包装”.“看,”奶牛们说,“如 ...

  3. js 无缝滚动效果学习

    <!DOCTYPE html> <html> <head> <title>无缝滚动测试</title> <meta http-equi ...

  4. 【Linux】df命令 ,查看磁盘容量。

    Oracle 导库时,失败,原因为磁盘满了, 记录下查看磁盘容量的指令 1.命令格式: df [选项] [文件] -a 全部文件系统列表 -h 方便阅读方式显示 -H 等于“-h”,但是计算式,1K= ...

  5. 解决Winform应用程序中窗体背景闪烁的问题

    本文转载:https://my.oschina.net/Tsybius2014/blog/659742 我的操作系统是Win7,使用的VS版本是VS2012,文中的代码都是C#代码. 这几天遇到一个问 ...

  6. jqgrid no url reset

    如果发现 jqgrid 在运行中出现次错误,可能是以下原因 $('#@(ViewBag.tabcid + "_grid")').jqGrid('navGrid', '#@(View ...

  7. MySQL Replication需要注意的问题

    MySQL Replication 大家都非常熟悉了,我也不会写怎么搭建以及复制的原理,网上相关文章非常多,大家可以自己去搜寻.我在这里就是想总结一下mysql主从复制需要注意的地方.有人说主从复制很 ...

  8. 在Unity中使用TDD - 初探

    描述 Editor Tests Runner是Unity中用来实现TDD的,其内部实现是基于NUnit. 其他 测试脚本要放在Editor文件夹中,测试要能够在一帧的时间内完成. 使用 打开Edito ...

  9. php 读取文件

    <?php /** *@param string $ip *@return string ip对应的地区 */ function getLocation($ip) { $ip_file_path ...

  10. hibernate学习(5)——多对多关系映射

    1.创建实体和映射 package com.alice.hibernate03.vo; import java.util.HashSet; import java.util.Set; public c ...