java线程学习之notify方法和notifyAll方法
notify(通知)方法,会将等待队列中的一个线程取出。比如obj.notify();那么obj的等待队列中就会有一个线程选中并且唤醒,然后被唤醒的队列就会退出等待队列。活跃线程调用等待队列中的线程时,因为现在的活跃线程还用有锁,会先将synchronized代码块执行完毕,释放对象监视器,被唤醒的线程才会获得这个监视器,然后被唤醒的线程才能继续执行。也就是说原来在等待队列中的线程被唤醒后,在被执行notify的一瞬间并不会立刻执行,因为在被执行notify的一瞬间,原来执行notify的线程还持有着锁,所以其他线程还无法获取这个实例的锁。
举个例子:假设熊大和熊二都要到小黑屋里面壁十分钟,小黑屋同一时刻只能允许一只熊进行面壁思过。熊大先进开始面壁思过同时把门锁上(相当于执行synchronized代码块拥有锁),结果在熊大面壁到三分钟的时候,困了想去睡觉(相当于执行wait()方法,进去到等待队列),这时它走出了门(相当于释放锁)去睡觉,熊二开始进来进行面壁思过,当熊二面壁到6分钟的时候,喊了一声让熊大接着来面壁思过(相当于执行notify方法),因为熊二还在继续面壁思过,所以熊大要在小黑屋外一直等,等到熊二面壁结束后(释放了锁),才能进去接着面壁,面壁剩余的七分钟,所以说即使熊二在第6分钟叫醒了熊大,但因为此时熊二在小黑屋里,熊大也不可能第一时间面壁思过。
如果说等待队列中的线程不止一个,那么当执行notify的时候叫醒那一个呢,被唤醒的线程是随机选择的。那么被唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。
notifyAll(通知全部)方法是将等待队列中的所以线程都唤醒,用法和notify一样。区别是notify只能唤醒等待队列中的一个,而notifyAll却能唤醒等待队列中的全部。
在实际使用时,是使用notify还是notifyAll,那个更好呢。
因为notify唤醒的线程比notifyAll少,所以notify的处理速度会更快。
使用notifyAll的代码要比使用notify的代码更健壮,因为使用notify如果处理不好,程序便有可能终止。
wait() ,notify()和notifyAll()方法都要获得此对象的监视器,也就是要获得锁,否则会报IllegalMonitorStateException异常
java线程学习之notify方法和notifyAll方法的更多相关文章
- Object类中wait代餐方法和notifyAll方法和线程间通信
Object类中wait代餐方法和notifyAll方法 package com.yang.Test.ThreadStudy; import lombok.SneakyThrows; /** * 进入 ...
- java数组、java.lang.String、java.util.Arrays、java.lang.Object的toString()方法和equals()方法详解
public class Test { public static void main(String[] args) { int[] a = {1, 2, 4, 6}; int[] b = a; in ...
- JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别
JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别 关于获取类的字段有两种方式:getFields()和getDeclaredFields().我们先来 ...
- Object类中wait带参方法和notifyAll方法和线程间通信
notifyAll方法: 进入到Timed_Waiting(计时等待)状态有两种方式: 1.sleep(long m)方法,在毫秒值结束之后,线程睡醒,进入到Runnable或BLocked状态 2. ...
- Java Thread中,run方法和start方法的区别
两种方法的区别: 1.start方法 用 start方法来启动线程,是真正实现了多线程, 通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦 ...
- [转]JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别
关于获取类的字段有两种方式:getFields()和getDeclaredFields().我们先来看看这两者的区别吧: getFields():获得某个类的所有的公共(public)的字段,包括父类 ...
- java.util.Scanner中hasNext()方法和next()方法的区别
先说结论: 两者均根据空格划分数据 两者在没有数据输入时均会等待输入 next()方法会将空格划分的数据依次输出,运行一次,输出一个 hasNext()方法会跟着next()方法移动,当前数据不为空, ...
- Java中Scanner中nextLine()方法和next()方法的区别
https://blog.csdn.net/hello_word2/article/details/54895106
- Object、String、数组的 toString() 方法和 equals() 方法及java.util.Arrays
public class Test { public static void main(String[] args) { int[] a = {1, 2, 4, 6}; int[] b = a; in ...
随机推荐
- Eureka源码解读
Eureka是我接触分布式软件和服务的第一个框架,所以其原理和实现我的好好研究一下,Eureka可以参看这篇博文:http://springcloud.cn/view/29 初学者会在教程中看到使用@ ...
- SpringMVC的坑
The request sent by the client was syntactically incorrect. 这个错误的原因是 因为 提交的表单数据和目标方法的入参不一致所导致 然后我就 ...
- Sum It Up---(DFS)
Sum It Up Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total S ...
- 秒杀linux下系统调用fork()面试题(转)
https://blog.csdn.net/chdhust/article/details/10579001 https://www.cnblogs.com/clover-toeic/p/375443 ...
- 微信小程序填坑之page[pages/XXX/XXX] not found.May be caused by
当页面出现 page[pages/XXX/XXX] not found.May be caused by :1. Forgot to add page route in app.json.2. I ...
- iOS8之后搜索框的常规实例
1.在一个二级导航控制器中添加一个UITableviewController作为子控制器 2.UITableviewController.tableView 作为展示结果 3.利用iOS之后的UISe ...
- Centos-7.4_安装_Redis_4.0.8
一.安装redis 第一步:下载redis安装包 [root@Redis ~]# mkdir /usr/local/redis/ --创建目录 [root@Redis redis]# cd /usr/ ...
- 《Redis 命令操作》
一:Redis 的启动与关闭 - 关闭指定端口的 Redis - redis-cli -p 9200 shutdown - 开启 Redis - redis-server redis.config 二 ...
- java手写线程池,完善中
package com.test001.threadpool; import java.util.LinkedList; import java.util.List; import java.util ...
- Angular+NodeJs+MongoDB搭建前后端程序
get请求: //angular 前端get请求 this.client.get('http://localhost:3000/id/tom').subscribe(data => { cons ...