线程间通信wait---notify
时间:2022-07-25
本文章向大家介绍线程间通信wait---notify,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、基本知识
- wait()方法可以使调用该方法的线程释放共享资源的锁,然后从运行状态退出,进入等待队列,直到被再次唤醒
- notify()方法可以随机唤醒等待队列中等待同一共享资源的“一个”线程,并使该线程退出等待队列,进入可运行状态,也就是notify()方法仅通知“一个”线程。
- notifyAll()方法可以使所有正在等待队列等待同一共享资源的“全部”线程从等待状态退出,进入可运行状态。此时,优先级最高的那个线程最先执行,但也有可能是随机执行,因为这要取决于JVM虚拟机的实现
二、示例
- 创建一个MyList类,作为公共资源类
public class MyList {
/**
* 必须添加volatile修饰符,不然在线程中会一直取私有堆栈的值,公共堆栈的值改变后取不到
*/
volatile private List<String> list = new ArrayList<>();
public void addElement(){
list.add("咖啡");
}
public int getSize(){
return list.size();
}
}
- 创建MyThreadA,该线程类主要发出“通知”
public class MyThreadA extends Thread {
private MyList list;
private Object lock;
public MyThreadA(MyList list, Object lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
try {
for (int i = 0; i < 10; i++) {
list.addElement();
System.out.println("已经添加了" + (i + 1) + "个元素了");
Thread.sleep(1000);
if (list.getSize() == 5){
//通知
lock.notify();
System.out.println("已发出通知了");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 创建MyThreadB,该线程主要进行wait,等待对象的通知
public class MyThreadB extends Thread {
private MyList list;
private Object lock;
public MyThreadB(MyList list, Object lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
synchronized (lock){
try {
PrintUtil.enterPrint("wait");
lock.wait();
PrintUtil.leavePrint("wait");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 进行调用
/**
* 个人理解:notify执行后发出通知,不过不会马上发出,需要当前方法执行完成之后才会发出,然后再有wait的方法接受的消息继续执行
*
* @Author: xjf
* @Date: 2019/6/7 8:57
*/
public class Main {
public static void main(String[] args) {
Object lock = new Object();
MyList list = new MyList();
//先运行threadB,让其进入等待状态
MyThreadB threadB = new MyThreadB(list,lock);
threadB.setName("B");
threadB.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
MyThreadA threadA = new MyThreadA(list,lock);
threadA.setName("A");
threadA.start();
}
}
- 有个自定义的打印工具类PrintUtil
/**
* 打印工具类
* @Author: xjf
* @Date: 2019/6/4 8:44
*/
public class PrintUtil {
/**
* 进入方法时的打印
* @param methodName
*/
public static void enterPrint(String methodName){
System.out.println("threadName=[" + Thread.currentThread().getName() + "] enter into methodName=[" +
methodName + "]. time=" + TimeUtil.convertToString(System.currentTimeMillis()));
}
/**
* 离开方法时的打印
* @param methodName
*/
public static void leavePrint(String methodName){
System.out.println("threadName=[" + Thread.currentThread().getName() + "] leave methodName=[" +
methodName + "]. time=" + TimeUtil.convertToString(System.currentTimeMillis()));
}
}
- 结果
threadName=[B] enter into methodName=[wait]. time=19-06-07 13:27:14
已经添加了1个元素了
已经添加了2个元素了
已经添加了3个元素了
已经添加了4个元素了
已经添加了5个元素了
已发出通知了
已经添加了6个元素了
已经添加了7个元素了
已经添加了8个元素了
已经添加了9个元素了
已经添加了10个元素了
threadName=[B] leave methodName=[wait]. time=19-06-07 13:27:25
Process finished with exit code 0
参考:《Java多线程编程核心技术》
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Guava - 布隆过滤器的使用
- [浅析] 特定场景下代替优化 if-else 的方案 (二)
- 面试官:mysql如何重置自增id
- 如何在kubernete集群上部署springboot应用
- lettuce连接池很香,撸撸它的源代码
- 浅谈kubernete中的flannel网络插件
- 聊聊Java中CompletableFuture的使用
- 开发更高可用、高质量的服务的一些建议
- kubernete编排技术一:pod
- Golang逃逸分析
- kubernete编排技术二:deployment
- Gearman介绍、原理分析、实践改进
- 『JWT』,你必须了解的认证登录方案
- 静态网站
- ansible超详细使用指南