精通java并发-wait,notify和notifyAll的总结(含案例)
目前CSDN,博客园,简书同步发表中,更多精彩欢迎访问我的gitee pages
wait,notify和notifyAll
总结
在调用wait方法时,线程必须要持有被调用对象的锁,当调用wait方法后,线程就会释放掉该对象的锁(monitor)
在调用Thread类的sleep方法时,线程是不会释放掉对象的锁的
- 当调用wait时,首先需要确保调用了wait方法的线程已经持有了对象的锁
- 当调用wait后,该线程就会释放掉这个对象的锁,然后进入到等待状态(wait set)
- 当线程调用了wait后进入到等待状态时,它就可以等待其他线程调用相同对象的notify或notifyAll方法来使得自己被唤醒
- 一旦这个线程被其他线程唤醒后,该线程就会与其他线程一同开始竞争这个对象的锁(公平竞争);只有当该线程获取到了这个对象的锁后,线程才会继续往下执行
- 调用wait方法的代码片段需要放在一个synchronized块或是synchronized方法中,这样才可以确保线程在调用wait方法前已经获取到了对象的锁
- 当调用对象的notify方法时,它会随机唤醒该对象等待集合(wait set)中的任意一个线程,当某个线程被唤醒后,它就会与其他线程一同竞争对象的锁
- 当调用对象的notifyAll方法时,它会唤醒该对象等待集合(wait set)中的所有线程,这些线程被唤醒后,又会开始竞争对象的锁
- 在某一时刻,只有唯一一个线程可以拥有对象的锁
案例
编写一个多线程程序,实现这样一个目标:
- 存在一个对象,该对象有一个int类型的成员变量counter,该成员变量的初始值为0.
- 创建两个线程,其中一个线程对该对象的成员变量counter增1,另一个线程对该对象的成员变量减1.
- 输出该对象成员变量counter每次变化后的值.
- 最终输出结果应为:101010101010.....
- 创建一个普通类MyObject,有成员变量counter,有一个使counter++的方法和一个使counter--的方法.
public class MyObject {
private int counter;
public synchronized void increase() {
while (counter != 0) {
try {
wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
counter++;
System.out.print(counter);
notify();
}
public synchronized void decrease() {
while (counter == 0) {
try {
wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
counter--;
System.out.print(counter);
notify();
}
}
- 创建一个调用MyObject的increase方法的线程类IncreaseThread
public class IncreaseThread extends Thread {
private MyObject myObject;
public IncreaseThread(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
for (int i = 0; i < 30; ++i) {
try {
Thread.sleep((long)(Math.random() * 1000));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
myObject.increase();
}
}
}
- 创建一个调用MyObject的decrease方法的线程类DecreaseThread
public class DecreaseThread extends Thread {
private MyObject myObject;
public DecreaseThread(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
for (int i = 0; i < 30; ++i) {
try {
Thread.sleep((long)(Math.random() * 1000));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
myObject.decrease();
}
}
}
- 创建一个含main方法的Client类
public class Client {
public static void main(String[] args) {
MyObject myObject = new MyObject();
Thread increaseThread = new IncreaseThread(myObject);
Thread increaseThread2 = new IncreaseThread(myObject);
Thread decreaseThread = new DecreaseThread(myObject);
Thread decreaseThread2 = new DecreaseThread(myObject);
increaseThread.start();
increaseThread2.start();
decreaseThread.start();
decreaseThread2.start();
}
}
- 执行结果

精通java并发-wait,notify和notifyAll的总结(含案例)的更多相关文章
- Java Thread wait, notify and notifyAll Example
Java Thread wait, notify and notifyAll Example Java线程中的使用的wait,notify和nitifyAll方法示例. The Object clas ...
- [译]Java Thread wait, notify和notifyAll示例
Java Thread wait, notify和notifyAll示例 Java上的Object类定义了三个final方法用于不同线程间关于某资源上的锁状态交互,这三个方法是:wait(), not ...
- java wait()和notify()、notifyAll()
图见<JAVA并发编程的艺术>P98-101 这三个方法都是java.lang.Object的方法,用于协调多个线程对共享数据的存取,必须在synchronized语句块中使用!这三个方法 ...
- Java的wait(), notify()和notifyAll()使用小结
wait(),notify()和notifyAll()都是java.lang.Object的方法: wait(): Causes the current thread to wait until an ...
- Java多线程 wait, notify 和 notifyAll
Java的Object类 public class Object { public final native void notify(); public final native void notif ...
- Java的wait(), notify()和notifyAll()使用心得(转)
本篇文章是对java的 wait(),notify(),notifyAll()进行了详细的分析介绍,需要的朋友参考下wait(),notify()和notifyAll()都是java.lang.Obj ...
- java中的notify和notifyAll有什么区别?
先说两个概念:锁池和等待池 锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入 ...
- 精通java并发-synchronized关键字和锁
目前CSDN,博客园,简书同步发表中,更多精彩欢迎访问我的gitee pages synchronized关键字和锁 示例代码 public class MyThreadTest2 { public ...
- Java 中 wait, notify 和 notifyAll的正确使用 – 以生产者消费者模型为例
如何使用Wait 尽管关于wait和notify的概念很基础,它们也都是Object类的函数,但用它们来写代码却并不简单.如果你在面试中让应聘者来手写代码,用wait和notify解决生产者消费者问题 ...
随机推荐
- Codeblocks 解决界面模糊的方法
之前用16.01不愿意升17.12的原因就是升级后界面变得非常模糊感觉很难看,找了个方法把这个问题解决了,这个方法能解决绝大多数软件打开后界面模糊的问题 (DEV模糊也能解决). 1.安装软件后桌面会 ...
- java中int和Integer的区别?为什么有了int还要有设计Integer?
参考https://blog.csdn.net/chenliguan/article/details/53888018 https://blog.csdn.net/myme95/article/det ...
- C++入门-控制台版的通讯录管理系统
通讯录管理系统 1.系统需求 通讯录是一个可以记录亲人.好友信息的工具. 本教程主要利用C++来实现一个通讯录管理系统 系统中需要实现的功能如下: 添加联系人:向通讯录中添加新人,信息包括(姓名.性别 ...
- c++无法解析的外部符号 "int const bufferSize
无法解析的外部符号 "int const bufferSize 严重性 代码 说明 项目 文件 行 禁止显示状态错误 LNK2001 无法解析的外部符号 "int const bu ...
- 第一章、认识Shiro
Shiro简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Securi ...
- v-if和v-show的使用和特点
v-if的特点是每次都会重新删除或创建操作 v-show的特点是每次不会进行DOM的删除和创建操作,只是切换了元素的display:none样式 <div id="app"& ...
- Spring Boot 2.x基础教程:Spring Data JPA的多数据源配置
上一篇我们介绍了在使用JdbcTemplate来做数据访问时候的多数据源配置实现.接下来我们继续学习如何在使用Spring Data JPA的时候,完成多数据源的配置和使用. 添加多数据源的配置 先在 ...
- JavaScript基础关于JSON(011)
JSON意即JavaScript Object Notation,是JavaScript里数据表示的通用格式,JSON数据格式很象JavaScript里的对象: {"name": ...
- java简介&&变量
Day01 简介 数据 1.数据大体分为两类:基本类型和引用类型 2.基本类型的数据分为四类八种,四类为整型,浮点,布尔,字符 3.Long类型的数据超过int范围要在之后面加个L,不加L是整型会进行 ...
- centos7 mysql8.0替换为5.7版本
今天按教程把mysql 的yum文件下载下来安装好,是8.0版本的,安装社区版的时候发现现在的8.0版本有1.7G那么大,就想重新安装5.7版本的,然后网上又找到一个5.7版本的yum,发现不能替换, ...