1.对于wait()和notify()的理解

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

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中的一个才有机会获得锁继续执行。

2.wait和notify简单使用示例

public class WaitNotifyTest {

    // 在多线程间共享的对象上使用wait
private String[] shareObj = { "true" }; public static void main(String[] args) {
WaitNotifyTest test = new WaitNotifyTest();
ThreadWait threadWait1 = test.new ThreadWait("wait thread1");
threadWait1.setPriority(2);
ThreadWait threadWait2 = test.new ThreadWait("wait thread2");
threadWait2.setPriority(3);
ThreadWait threadWait3 = test.new ThreadWait("wait thread3");
threadWait3.setPriority(4); ThreadNotify threadNotify = test.new ThreadNotify("notify thread"); threadNotify.start();
threadWait1.start();
threadWait2.start();
threadWait3.start();
} class ThreadWait extends Thread { public ThreadWait(String name){
super(name);
} 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("线程" + getName() + "等待结束");
}
} class ThreadNotify extends Thread { public ThreadNotify(String name){
super(name);
} 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() + "运行结束");
}
}
}

运行结果:

线程wait thread1开始等待
线程wait thread3开始等待
线程wait thread2开始等待
线程notify thread开始准备通知
线程notify thread通知结束
线程notify thread运行结束
线程wait thread2等待时间为:2998
线程wait thread2等待结束
线程wait thread3等待时间为:2998
线程wait thread3等待结束
线程wait thread1等待时间为:3000
线程wait thread1等待结束

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

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

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

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

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

  3. wait()和notify()的理解与使用

    void notify() Wakes up a single thread that is waiting on this object’s monitor. 译:唤醒在此对象监视器上等待的单个线程 ...

  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. Android中Socket通信之TCP与UDP传输原理

    一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时 ...

  2. 【Unity Shaders】Alpha Test和Alpha Blending

    写在前面 关于alpha的问题一直是个比较容易摸不清头脑的事情,尤其是涉及到半透明问题的时候,总是不知道为什么A就遮挡了B,而B明明在A前面.这篇文章就总结一下我现在的认识~ Alpha Test和A ...

  3. Windows下多线程数据同步互斥的有关知识

     对于操作系统而言,在并行程序设计中难免会遇到数据同步和共享的问题,本文针对这个问题,以windows系统为例回顾一下资源同步的相关问题.要点如下: 1.同步和数据共享  数据征用 2.同步原语 ...

  4. 【shell脚本】mysql每日备份shell脚本

    每天固定时间用mysqldump 备份mysql数据. #!/bin/bash #每天早上4点, mysql备份数据 orangleliu #chmod 700 backup.sh #crontab ...

  5. [GitHub]第四讲:合并分支

    本地两个分支合并 先从最简单的一种情况着手.现在项目只有一个 master 分支,我来新建一个 idea 分支,实现自己的想法,commit 一下.那现在仓库内的情况就是这样的 这个是前面已经见过的情 ...

  6. win7 VMware CentOS桥接(bridge)模式网络配置

    主要内容参考自: centos下vmware 桥接设置静态ip例子 关于虚拟机网络配置的文章: Win7+VMware Workstation环境下的CentOS-Linux网络连接设置(推荐阅读) ...

  7. android 解析服务器数据使用json还是xml方式

    整理自百度搜索: 现在的Android应用程序,几乎没有不与服务端交换数据的了!那么,android应用在与服务端交换数据的时候,我们有哪些选择呢?哪种数据交换格式要更好吗?下面文章简单为 andro ...

  8. Mahout推荐算法之ItemBased

    Mahout推荐之ItemBased 一.   算法原理 (一)    基本原理 如下图评分矩阵所示:行为user,列为item. 图(1) 该算法的原理: 1.  计算Item之间的相似度. 2.  ...

  9. C语言--字符串和数字的相互转换

    1.数字转换为字符串 sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出. sprintf 是个变参函数,定义如下: int sp ...

  10. Java Map 及相应的一些操作总结

    Map是我们在开发的时候经常会用到的,大致有以下几个操作,其中putAll方法是针对集合而言的操作,故不再进行说明,下面请看一下常用的知识点吧,尤其是keySet和Values两个方法及相应值的获取方 ...