关于java的wait、notify、notifyAll方法
wait、notify、notifyAll
遇到的问题
之前开发打印机项目,因为需要使用多线程技术,当时并不怎么理解,一开始随意在方法体内使用wait、notify、notifyAll 方法导致出现了一大堆 IllegalMonitorStateException 异常。为什么会出现这个异常这和这三个方法内部的机制有关。
同步机制
wait 和 notify 是 java 同步机制中重要组成部分。使用时需结合 synchronized 关键字。
同步分为类级别和对象级别,分别对应着类锁和对象锁。其实类也可以看成是一个 Class 对象。每个类只有一个类锁,每个对象也只有一个对象锁。要想达到同步状态,操作时必须获取对应的对象/类锁,保证其他地方不能同时更改对象/类的状态。
关于 wait、notify、notifyAll
- wait
调用wait的时候,线程会释放其占有的对象锁,同时不会主动去申请获取对象锁,必须等待被唤醒的时候,才拥有获得对象锁的权利。 - notify
唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个对象在等待,而且具有随机性) - -notifyAll
唤醒所有在等待该对象同步锁的线程,该方法虽然是对每个wait的线程都调用一次notify,但还是有顺序的,每个对象都保存这一个等待对象链,调用的顺序就是这个链的顺序。
注:
调用了wait、notify、notifyAll 方法必须在同步状态,即已获取了对象锁,所以在使用时候必须搭配 synchronized 关键字一起用,否则就会抛出 java.lang.IllegalMonitorStateException ,所以之前遇到的问题就是因为在没有保证同步的时候调用了这些方法。
notifyAll 虽然能唤醒所有线程,但并不是所有线程立刻获得执行的机会,因为要获得执行的机会,必须首先获得对象锁,但是同一时刻只有线程能够获得对象锁。所以在调用 notifyAll 方法之后,同一时刻只有一个线程获得执行的机会,其他线程须等待该线程执行完毕释放对象锁才有机会执行
这三个方法都属于Object对象,而不属于线程级别,它们的使用都与锁有关
关于java的wait、notify、notifyAll方法的更多相关文章
- Java多线程_wait/notify/notifyAll方法
关于这三个方法,我们可以查询API得到下列解释: wait():导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法或者指定的事件用完 notify( ...
- java 为什么wait(),notify(),notifyAll()必须在同步(Synchronized)方法/代码块中调用?
wait()作用:该方法用来将当前线程置入休眠状态,直到接到通知或被中断为止.条件:在调用wait()之前,线程必须要获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法.进入wai ...
- java使用wait(),notify(),notifyAll()实现等待/通知机制
public class WaitNotify { static boolean flag=true; static Object lock=new Object(); static class Wa ...
- java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
在Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity.所有对象的非同步方法都能够在任意时刻被任意线程调用 ...
- [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
在 Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity. 所有对象的非同步 方法都能够在任意时刻被任意线 ...
- 为什么 wait()方法和 notify()/notifyAll()方法要在同步块 中被调用 ?
这是 JDK 强制的,wait()方法和 notify()/notifyAll()方法在调用前都必须先获得对 象的锁
- Java多线程--wait(),notify(),notifyAll()的用法
忙等待没有对运行等待线程的 CPU 进行有效的利用(而且忙等待消耗cpu过于恐怖,请慎用),除非平均等待时间非常短.否则,让等待线程进入睡眠或者非运行状态更为明智,直到它接收到它等待的信号. Java ...
- Java通过wait()和notifyAll()方法实现线程间的通信
Java代码(使用了2个内部类): package Threads; import java.util.LinkedList; /** * Created by Frank */ public cla ...
- Java多线程8:wait()和notify()/notifyAll()
轮询 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A线程做int型变量i的累加操作,B线程等待i到了10000就打印出i,怎么处 ...
- [译]Java Thread wait, notify和notifyAll示例
Java Thread wait, notify和notifyAll示例 Java上的Object类定义了三个final方法用于不同线程间关于某资源上的锁状态交互,这三个方法是:wait(), not ...
随机推荐
- SAP Cloud for Customer Sales Order Requested Date的业务含义和实现
我们在创建Sales order销售订单时,需要指定一个RequestedDate: 这个字段绑定到了BO字段:CustomerQuote.RequestedFulfillmentPeriod.Tim ...
- python UI自动化实战记录十一: 总结
首先说说为什么想起来用自动化脚本来实现该项目的自动化. 工作还是以手工测试为主,业务驱动型的项目大概就是这样,业务不停地变,不断的迭代. 自动化测试实施的先决条件: 一 得有时间. 如果有时间大部分的 ...
- Executor线程池框架
Executor线程池框架 new Thread()的缺点 每次new Thread()耗费性能 调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞争,会导致 ...
- django 外键操作
下面定义两个模型,一个主表,一个字表. 举例说明: 如何通过主表对象找到对应的子表对象? 如何通过子表对象找到对应的主表对象? class Person(models.Model); name = m ...
- Unix shell输入输出重定向
敲代码的时候,适当地打印出一些进度或者日志信息经常能帮助我们跟踪程序的执行结果.可是,这些结果或者日志打印信息到屏幕上并不能作为以后检查问题的根据.这就是重定向的作用,敲代码的时候,我们能够方便的将相 ...
- Mac常备必用的软件-mac软件推荐
目录 终端工具 iTerm2,做开发的都用它代替系统自带的“终端”,免费软件,官网直接下载即可. 文件比较工具 meld,开源免费的文件/文本比较工具. 安装方法:brew cask install ...
- git及github配置入门
github是一个有海量开源代码库的网站,同时也是一个软件开发管理软件,作为软件来说它集成了git这个分布式的版本控制系统,可以上传.下载和管理自己的代码. 笔者刚接触不久,把认为入门应该知道的东西稍 ...
- HDU 1166 【线段树 || 树状数组,单点修改 维护区间和】
题目链接 HDU 1166 大概题意: 第一行一个整数T,表示有T组数据.每组数据第一行一个正整数N(N<=50000),表示敌人有N个工兵营地,接下来有N个正整数,第i个正整数ai代表第i个工 ...
- React Native开发中自动打包脚本
React Native开发中自动打包脚本 在日常的RN开发中,我们避免不了需要将我们编写的代码编译成安装包,然后生成二维码,供需要测试的人员扫描下载.但是对于非原生的开发人员来说,可能不知如何使用X ...
- chromium之message_pump_win之一
写了22篇博文,终于到这里了———— MessagePumpWin!!! MessagePumpWin这个类还是挺复杂的,可以分成好几部分.接下来分块分析 从介绍看,MessagePumpWin 是M ...