void notify()
Wakes up a single thread that is waiting on this object’s monitor.
译:唤醒在此对象监视器上等待的单个线程 void notifyAll()
Wakes up all threads that are waiting on this object’s monitor.
译:唤醒在此对象监视器上等待的所有线程 void wait( )
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll( ) method for this object.
译:导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法 void wait(long timeout)
Causes the current thread to wait until either another thread invokes the notify( ) method or the notifyAll( ) method for this object, or a specified amount of time has elapsed.
译:导致当前的线程等待,直到其他线程调用此对象的notify() 方法或 notifyAll() 方法,或者指定的时间过完。 void wait(long timeout, int nanos)
Causes the current thread to wait until another thread invokes the notify( ) method or the notifyAll( ) method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.
译:导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法,或者其他线程打断了当前线程,或者指定的时间过完。

上面是官方文档的简介,下面我们根据官方文档总结一下:

  • wait( ),notify( ),notifyAll( )都不属于Thread类,而是属于Object基础类,也就是每个对象都有wait( ),notify( ),notifyAll( ) 的功能,因为每个对象都有锁,锁是每个对象的基础,当然操作锁的方法也是最基础了。

  • 当需要调用以上的方法的时候,一定要对竞争资源进行加锁,如果不加锁的话,则会报 IllegalMonitorStateException 异常

  • 当想要调用wait( )进行线程等待时,必须要取得这个锁对象的控制权(对象监视器),一般是放到synchronized(obj)代码中。

  • 在while循环里而不是if语句下使用wait,这样,会在线程暂停恢复后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知

  • 调用obj.wait( )释放了obj的锁,否则其他线程也无法获得obj的锁,也就无法在synchronized(obj){ obj.notify() } 代码段内唤醒A。

  • notify( )方法只会通知等待队列中的第一个相关线程(不会通知优先级比较高的线程)

  • notifyAll( )通知所有等待该竞争资源的线程(也不会按照线程的优先级来执行)

  • 假设有三个线程执行了obj.wait( ),那么obj.notifyAll( )则能全部唤醒tread1,thread2,thread3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,tread1,thread2,thread3只有一个有机会获得锁继续执行,例如tread1,其余的需要等待thread1释放obj锁之后才能继续执行。

  • 当调用obj.notify/notifyAll后,调用线程依旧持有obj锁,因此,thread1,thread2,thread3虽被唤醒,但是仍无法获得obj锁。直到调用线程退出synchronized块,释放obj锁后,thread1,thread2,thread3中的一个才有机会获得锁继续执行。

测试用例:

 package test;

 /**
* @author zsh
* @company wlgzs
* @create 2019-02-25 9:02
* @Describe 多线程方法wait() and notify() 方法测试
*/
public class WaitNotifyTest { // 在多线程间共享的对象上使用wait
private String[] shareObj = {"true"}; //线程等待
class ThreadWait extends Thread{ public ThreadWait(String name){
super(name);
} @Override
public void run() {
synchronized (shareObj){
while ("true".equals(shareObj[0])){
System.out.println("线程"+this.getName()+"开始等待");
long startTime = System.currentTimeMillis();
try {
shareObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("线程"+this.getName()+"等待的时间为"+
(endTime - startTime));
}
}
System.out.println("线程" + this.getName() + "等待结束");
}
} //线程唤醒
class ThreadNotify extends Thread{ public ThreadNotify(String name){
super(name);
} @Override
public void run() {
try {
// 给等待线程等待时间
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (shareObj){
System.out.println("线程" + this.getName() + "开始准备通知");
shareObj[0] = "false";
shareObj.notifyAll();
System.out.println("线程" + this.getName() + "通知结束");
}
System.out.println("线程" + this.getName() + "运行结束");
}
} public static void main(String[] args) {
WaitNotifyTest waitNotifyTest = new WaitNotifyTest();
ThreadWait threadWait1 = waitNotifyTest.new ThreadWait("wait thread1");
/**
* 优先级 : 只能反映线程的 重要程度 或者是 紧急程度 , 不能决定 是否一定先执行
* setPriority()
* 1~10 1最低 10最高 5是默认值
*/
threadWait1.setPriority(2);
ThreadWait threadWait2 = waitNotifyTest.new ThreadWait("wait thread2");
threadWait2.setPriority(3);
ThreadWait threadWait3 = waitNotifyTest.new ThreadWait("wait thread3");
threadWait3.setPriority(4); ThreadNotify threadNotify = waitNotifyTest.new ThreadNotify("notify thread"); threadNotify.start();
threadWait1.start();
threadWait2.start();
threadWait3.start();
} }

wait()和notify()的理解与使用的更多相关文章

  1. wait和notify的理解与使用

    1.对于wait()和notify()的理解 对于wait()和notify()的理解,还是要从jdk官方文档中开始,在Object类方法中有: void notify() Wakes up a si ...

  2. 多线程中wait和notify的理解与使用

    1.对于wait()和notify()的理解 对于wait()和notify()的理解,还是要从jdk官方文档中开始,在Object类方法中有: void notify()  Wakes up a s ...

  3. 对await(),notify()的理解

    await(),notify()是java Object类的方法.在两个线程同时访问一个对象的时候可以利用这2个方法实现线程的通信.看下面的例子. public class Account { pri ...

  4. Object对象你真理解了吗?

    前言 五一回家又断更了一个放假时间了~~~ 只有光头才能变强 回顾前面: ThreadLocal就是这么简单 多线程三分钟就可以入个门了! 多线程基础必要知识点!看了学习多线程事半功倍 Java锁机制 ...

  5. 使用wait/notify实现线程间的通信

    之前对Java多线程中的wait/notify机制理解都不是很清晰,最近看了一本技术书,通过里面的讲解再配上一些博客,终于算是对wait/notify有了进一步的理解. 下面就来说说我对这两个方法的认 ...

  6. 2015年阿里巴巴蚂蚁金服校招JAVA研发工程师内推电话面试

    没想到阿里校招如此之早,虽然早已进入复习备战状态,但还是感觉有些措手不及...找了个在蚂蚁金服做HR的同学帮忙了内推,然后在最近的几天匆匆忙忙地复习JAVA(之前都把精力放在了数据结构.算法等基础上了 ...

  7. ansible-playbook用法

    一.playbook用法 1.playbook的执行文件为YAML语言编写,所以文件名为xxx.yml.YAML语法可以参考https://docs.ansible.com/ansible/lates ...

  8. OO第二单元小结

    OO第二单元小结 一.三次作业代码分析. 1.第一次作业 第一次作业是单部电梯的傻瓜调度,由于其过分傻瓜,所以第一次作业我只有两个类,一个main,一个电梯,main类负责不断从输入流中读取命令,如果 ...

  9. Android - Android 面试题集

    1.Java部分 1.1 操作系统相关 1.什么是操作系统? 2.什么是线程,什么是进程? 1.2 JDK&JVM&JRE 1.JDK & JVM & JRE分别是什么 ...

随机推荐

  1. 兼容PC和手机触摸代码

    测试环境:unity3d 4.6.1 using UnityEngine; using System.Collections; public class neccc : MonoBehaviour { ...

  2. 解决Nginx重启时提示nginx: [emerg] bind() to 0.0.0.0:80错误

    Nginx是一款轻量级的Web服务器,特点是占有内存少,并发能力强,因而使用比较广泛,蜗牛今天在一个VPS上重启Nginx时提示“nginx: [emerg] bind() to 0.0.0.0:80 ...

  3. 编写一种递归方法,它返回数N的二进制中表示1的个数。

    /** * 编写一种递归方法,它返回数N的二进制中表示1的个数.利用这样一个事实:N为奇数,其1的个数为N/2的二进制中1的个数加1. * @author wulei * */public class ...

  4. Git安装及创建版本库

    一.在Windows上安装Git 1.虽然用于开发的系统最好是用Mac或者Linux,但绝大多数新人都是用Windows进行开发.Windows系统上也有提供了Git(Windows版),下载地址:h ...

  5. MYSQLi数据访问批量删除

    <link href="../bootstrap.min.css" rel="stylesheet" type="text/css" ...

  6. python复习冒泡排序

    冒泡排序: 思路: 先找到最大值放到最右边: #encoding=utf-8 a=[1,9,2,8,3,6,4] print "a before change:",a for i ...

  7. 加密对象到locastorage / 从 locastorage解密对象

    var obj={name:"致远",age:21,address:"江西上饶XXXX",hobby:"看书,编程"};//用中文 记得加e ...

  8. Qt浅谈之一:内存泄露(总结)

    一.简介       Qt内存管理机制:Qt 在内部能够维护对象的层次结构.对于可视元素,这种层次结构就是子组件与父组件的关系:对于非可视元素,则是一个对象与另一个对象的从属关系.在 Qt 中,在 Q ...

  9. linux mysql主从复制

    centos7 安装 mariadb 1 yum 源  -- 配置阿里的 2 rmp 方式 3 源码编译方式  -- 专业DBA 一些知识点: 虚拟环境 不影响 redis/ mariadb/mysq ...

  10. 监控网卡流量脚本(Python)

    #!/usr/bin/env python# coding: utf-8# author: Xiao Guaishou try:    import psutilexcept ImportError: ...