notify() 和 notifyAll()方法的使用和区别
一、区别
notify()和notifyAll()都是用来用来唤醒调用wait()方法进入等待锁资源队列的线程,区别在于:
notify()
唤醒正在等待此对象监视器的单个线程。 如果有多个线程在等待,则选择其中一个随机唤醒(由调度器决定),唤醒的线程享有公平竞争资源的权利
notifyAll()
唤醒正在等待此对象监视器的所有线程,唤醒的所有线程公平竞争资源
二、示例
notify()
public class ThreadDemo implements Runnable{static Object lock = new Object();public static void main(String[] args) {Thread thread1 = new Thread(new ThreadDemo(), "Thread-a");Thread thread2 = new Thread(new ThreadDemo(), "Thread-b");thread1.start();thread2.start();try {TimeUnit.SECONDS.sleep(1); // 睡会,让走到子线程} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock) {System.out.println(Thread.currentThread().getName() + " 获得了锁");System.out.println("notify前" + thread1.getName() + "状态是" + thread1.getState());System.out.println("notify前" + thread2.getName() + "状态是 " + thread2.getState());lock.notify(); // 唤醒一个等待lock锁的线程}try {TimeUnit.MILLISECONDS.sleep(300); // 睡会,让被唤醒的子线程走完} catch (InterruptedException e) {e.printStackTrace();}System.out.println("notify后" + thread1.getName() + "状态是" + thread1.getState());System.out.println("notify后" + thread2.getName() + "状态是" + thread2.getState());}@Overridepublic void run() {synchronized (lock) {System.out.println(Thread.currentThread().getName() + " 获得了锁");try {lock.wait(); // 等待被唤醒} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " end");}}
}
结果:
可以看到,子线程在wait()后释放了锁并进入WAITTINT状态,主线程获得锁后调用notify(),这时候其中一个线程(栗子中是Thread-b,也有可能是a)被唤醒并获取到锁继续执行到TERMINATED,而另一个线程a一直WAITTINT状态
Thread-b 获得了锁
Thread-a 获得了锁
main 获得了锁
notify前Thread-a状态是WAITING
notify前Thread-b状态是 WAITING
Thread-b end
notify后Thread-a状态是WAITING
notify后Thread-b状态是TERMINATED
notifyAll()
上面的栗子如果使用notifyAll(),看下结果
public class ThreadDemo implements Runnable{static Object lock = new Object();public static void main(String[] args) {Thread thread1 = new Thread(new ThreadDemo(), "Thread-a");Thread thread2 = new Thread(new ThreadDemo(), "Thread-b");thread1.start();thread2.start();try {TimeUnit.SECONDS.sleep(1); // 睡会,让走到子线程} catch (InterruptedException e) {e.printStackTrace();}System.out.println("哈哈哈哈");synchronized (lock) {System.out.println(Thread.currentThread().getName() + " 获得了锁");System.out.println("notify前" + thread1.getName() + "状态是" + thread1.getState());System.out.println("notify前" + thread2.getName() + "状态是 " + thread2.getState());lock.notifyAll(); // 唤醒所有等待lock锁的线程}try {TimeUnit.MILLISECONDS.sleep(300); // 睡会,让被唤醒的子线程走完} catch (InterruptedException e) {e.printStackTrace();}System.out.println("notify后" + thread1.getName() + "状态是" + thread1.getState());System.out.println("notify后" + thread2.getName() + "状态是" + thread2.getState());}@Overridepublic void run() {synchronized (lock) {System.out.println(Thread.currentThread().getName() + " 获得了锁");try {lock.wait(); // 等待被唤醒} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " end");}}
}
结果,可以看到所有子线程都被唤醒并再次公平竞争锁直到线程终止
Thread-b 获得了锁
Thread-a 获得了锁
哈哈哈哈
main 获得了锁
notify前Thread-a状态是WAITING
notify前Thread-b状态是 WAITING
Thread-a end
Thread-b end
notify后Thread-a状态是TERMINATED
notify后Thread-b状态是TERMINATED
notify() 和 notifyAll()方法的使用和区别相关推荐
- 【面试题】notify() 和 notifyAll()方法的使用和区别
[面试题]notify() 和 notifyAll()方法的使用和区别 Java中notify和notifyAll的区别 何时在Java中使用notify和notifyAll? [问]为什么wait( ...
- Object的notify和notifyAll方法的区别
区别 notify:只会唤醒等待该锁的其中一个线程. notifyAll:唤醒等待该锁的所有线程. 既然notify会唤醒一个线程,并获取锁,notifyAll会唤醒所有线程并根据算法选取其中一个线程 ...
- Object类九大方法之notify和notifyAll方法
Object类九大方法之notify和notifyAll方法 notify()方法表示,当前的线程已经放弃对资源的占有, 通知等待的线程来获得对资源的占有权,但是只有一个线程能够从wait状态中恢复, ...
- 为什么wait、notify、notifyAll方法定义在Object中而不是Thread类中
多线程概述 Java是一个支持多线程的开发语言,多线程并发执行任务可以充分利用CPU资源,提高多任务并发执行效率(注意区分:多线程并不会加快任务的执行速度,而是可以充分利用多核CPU让线程轮流进行工作 ...
- 第五章 Java 中的 wait、notify 和 notifyAll 方法示例
您可能已经注意到 Object 类具有三个 final 方法,分别称为 wait.notify 和 notifyAll.这些方法用于线程间通信.Java 5 引入了执行器框架,它为您处理线程间通信,并 ...
- Object的wait、notify和notifyAll方法
方法简介 wait方法 当一个线程调用一个共享变量的wait()方法时,该调用线程会被阻塞挂起(进入waiting状态),直到发生下面几件事情之一才能返回: 其他线程调用了该共享对象的notify() ...
- Java中notify和notifyAll的区别 - 何时以及如何使用
Java notify vs notifyAll notify和notifyAll方法之间有什么区别是棘手的Java问题之一! Condition 是个什么玩意? 提几个问题,从问题中去了解去学 ...
- Java并发07:Thread的基本方法(4)-Thread.sleep()、Object.wait()、notify()和notifyAll()
[超级链接:Java并发学习系列-绪论] 本章主要对Java中Thread类的基本方法进行学习. 1.序言 Thread类作为线程的基类,提供了一系列方法,主要有: Thread.sleep(long ...
- Java之notify和notifyAll区别
在Java中notify()和notifyAll()方法都是Object对象用于通知处在等待该对象的线程的方法. 两者的最大区别在于: notifyAll方法 使所有原来在该对象上等待被notify的 ...
最新文章
- torch中的copy()和clone()
- 神经网络的演变与发展(Part 2)
- LeetCode刷题第二天——3Longest Substring Without repeating character 4 Median of Two Sorted Arrays...
- 转载:警惕!!骗人的“培训机构” “北大青鸟”事件
- es6 属性的可枚举性和遍历
- 东风本田4S店违规收取续保押金 ,电台主持在线怒怼经理,反被指无教养?
- OpenShift 4 - 使用ArgoCD Operator
- C语言系列之自增自减运算符的用法(二)
- Java判断是否为移动端
- 2.1.0 Python初识面向对象
- Atitit 提升扩展性指标与方法总结 目录 1. 扩展性常见指标	1 1.1. 代码简洁,应业务变动调整修改少	1 1.2. 免编译	1 1.3. 是否支持热部署	2 2. 常见的方法策略	2
- Atitit 软件集成法 eai 目录 1. 表示集成 ui界面集成 最简单	1 2. 数据集成	1 3. 控制集成 功能集成 应用集成	1 4. 业务流程集成	1 5. 企业应用集成	1
- 电磁兼容性(EMC)标准EN55032IT设备要求
- 新手建站推广完美教程(重点推荐)
- bulma.css_在5分钟内学习Bulma CSS-初学者教程
- wordpress添加备案链接 亲测无误
- 如何用电脑画平面坐标图_如何画坐标图?
- 6个适合成年人的自学网站,每天半小时改变你一生
- matlab 经典循环语句,经典MATLAB循环语句
- 微信中各种代码/符号合集