通常,多线程之间需要协调工作。例如,浏览器的一个显示图片的线程displayThread想要执行显示图片的任务,必须等待下载线程 downloadThread将该图片下载完毕。如果图片还没有下载完,displayThread可以暂停,当downloadThread完成了任务 后,再通知displayThread“图片准备完毕,可以显示了”,这时,displayThread继续执行。

以上逻辑简单的说就是:如果条件不满足,则等待。当条件满足时,等待该条件的线程将被唤醒。在Java中,这个机制的实现依赖于wait/notify。等待机制与锁机制是密切关联的。例如:
synchronized(obj) {while(!condition) {obj.wait();}obj.doSomething();}

当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait()。
在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:
synchronized(obj) {condition = true;obj.notify();}

需要注意的概念是:
◆调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {...} 代码段内。
◆调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {...} 代码段内唤醒A。
◆当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。
◆如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。
◆obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。
◆当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。

转自:https://www.cnblogs.com/txdlf/p/5344122.html

Java中wait()与notify()理解的更多相关文章

  1. Java中线程同步的理解 - 其实应该叫做Java线程排队

    Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...

  2. java中线程同步的理解(非常通俗易懂)

    转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...

  3. 多线程中wait、notify理解

    实在惭愧,java开发多年,多线程运用一直不多,该知识点理解也不够,不怎么会用.赶上使用多线程 生产者.消费者模式,学习下该知识点. synchronized  获取锁 wait 阻塞本线程,释放对象 ...

  4. java中wait和notify

    在JAVA中,是没有类似于PV操作.进程互斥等相关的方法的.JAVA的进程同步是通过synchronized()来实现的,需要说明的是,JAVA的synchronized()方法类似于操作系统概念中的 ...

  5. 线程:Java中wait、notify、notifyAll使用详解

    基础知识 首先我们需要知道,这几个都是Object对象的方法.换言之,Java中所有的对象都有这些方法. public final native void notify(); public final ...

  6. 微冷的雨之Java中的多线程初理解(一)

    在讲解多线程前,我们必须理解什么是多线程?而且很多人都会将进程和线程做对比. 进程和线程 进程:进程是操作系统结构的基础,是一次程序的执行,是一个程序及其数据在处理机上顺序执行时所发生的活动,是程序在 ...

  7. 对Java中字符串的进一步理解

    字符串在程序开发中无处不在,也是用户交互所涉及到最频繁的数据类型,那么字符串不仅仅就是我们简单的理解的String str = "abc";一起来更加深入的看一下 在Java中,字 ...

  8. Java中的ThreadLocal深入理解

    提到ThreadLocal,有些Android或者Java程序员可能有所陌生,可能会提出种种问题,它是做什么的,是不是和线程有关,怎么使用呢?等等问题,本文将总结一下我对ThreadLocal的理解和 ...

  9. Java学习疑惑(8)----可视化编程, 对Java中事件驱动模型的理解

    我们编写程序就是为了方便用户使用, 我觉得UI设计的核心就是简洁, 操作过于繁琐的程序让很大一部分用户敬而远之. 即使功能强大, 但是人们更愿意使用易于操作的软件. 近年流行起来的操作手势和逐渐趋于成 ...

随机推荐

  1. spring boot工程如何启用 热启动功能

    1.在pom.xml里面添加一个依赖即可 关键代码 <dependency> <groupId>org.springframework.boot</groupId> ...

  2. Python安装pip3

    在新的电脑上,偶尔会出现无法安装pip的问题. 今天看见了一位大神的方法: 在cmd窗口中输入python -m ensurepip 然后使用pip命令安装其他包.pip3 install 模块名 说 ...

  3. mysql语句(二)

    --MySQL 连接的使用 JOIN 按照功能大致分为如下三类: INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录. LEFT JOIN(左连接):获取左表所有记录,即使右表 ...

  4. 在Ubuntu中搭建Python3的虚拟环境并开始django项目

    搭建环境: 1.首先安装virtualenv: pip install virtualenv 2.创建虚拟环境:(指定安装Python3,若不写-p python3,默认安装Python2.7),en ...

  5. springboot @vaule注解失效解决办法

    在Controller类里面通过@Value将参数注入进来,最后的确成功了.因此基于此经验,我便在其他使用的类里面也采用这样的方式注入参数,但是发现去失效了,报错为NULL,说明参数并没有我们料想的被 ...

  6. java日期比较工具类

    package com.net.util; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.ut ...

  7. hdu4813 01背包+前缀和

    题意:\(A,B\)两人,有\(N\)个事件,每件发生的概率都为\(0.5\),若事件\(i\)发生,则\(B\)加\(v_i\)分数,若其不发生,则\(B\)不加分,给定一个概率\(P\),问至少需 ...

  8. 数据库设计规范、E-R图、模型图

    (1)数据库设计的优劣: 糟糕的数据库设计: ①数据冗余冗余.存储空间浪费. ②数据更新和插入异常. ③程序性能差. 良好的数据库设计 ①节省数据的存储空间. ②能够保证数据的完整新. ③方便进行数据 ...

  9. Unity上线google商店 用IL2Cpp打包64位版本和Android APP Bundle优化 及产生的bug

    ios刚上线,这边着手改成android版本,我开始使用的是unity2017.4.1版本 上传谷歌商店是出现这两个警告: 要支持64位,但是在2017版本上没有找到64位的打包选项,猜测应该是版本的 ...

  10. 安装笔记, caffe 、 opencv等

    1. 1.1 opencv static linux mkdir build & cd build cmake .. -LH  这句话用来查看编译选项  如果不知道编译啥  可以用这个查看一下 ...