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方法的更多相关文章

  1. Java多线程_wait/notify/notifyAll方法

    关于这三个方法,我们可以查询API得到下列解释: wait():导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法或者指定的事件用完 notify( ...

  2. java 为什么wait(),notify(),notifyAll()必须在同步(Synchronized)方法/代码块中调用?

    wait()作用:该方法用来将当前线程置入休眠状态,直到接到通知或被中断为止.条件:在调用wait()之前,线程必须要获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法.进入wai ...

  3. java使用wait(),notify(),notifyAll()实现等待/通知机制

    public class WaitNotify { static boolean flag=true; static Object lock=new Object(); static class Wa ...

  4. java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?

    在Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity.所有对象的非同步方法都能够在任意时刻被任意线程调用 ...

  5. [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?

    在 Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity. 所有对象的非同步 方法都能够在任意时刻被任意线 ...

  6. 为什么 wait()方法和 notify()/notifyAll()方法要在同步块 中被调用 ?

    这是 JDK 强制的,wait()方法和 notify()/notifyAll()方法在调用前都必须先获得对 象的锁

  7. Java多线程--wait(),notify(),notifyAll()的用法

    忙等待没有对运行等待线程的 CPU 进行有效的利用(而且忙等待消耗cpu过于恐怖,请慎用),除非平均等待时间非常短.否则,让等待线程进入睡眠或者非运行状态更为明智,直到它接收到它等待的信号. Java ...

  8. Java通过wait()和notifyAll()方法实现线程间的通信

    Java代码(使用了2个内部类): package Threads; import java.util.LinkedList; /** * Created by Frank */ public cla ...

  9. Java多线程8:wait()和notify()/notifyAll()

    轮询 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A线程做int型变量i的累加操作,B线程等待i到了10000就打印出i,怎么处 ...

  10. [译]Java Thread wait, notify和notifyAll示例

    Java Thread wait, notify和notifyAll示例 Java上的Object类定义了三个final方法用于不同线程间关于某资源上的锁状态交互,这三个方法是:wait(), not ...

随机推荐

  1. 如何用jstl的select标签做二级联动下拉列表框??

    下拉列表框的多级联动早就会了.但是用jstl的select标签做下拉列表框的做二级联动的时候还是遇到了些问题.主要问题在用Ajax查询到的数据如何拼成下拉选项的时候.其实很简单,但我还是折腾了好久.所 ...

  2. Oracle 数据库视图与基表的关系

    本文转载自:http://www.linuxidc.com/Linux/2015-03/115165.htm 一:首先解释什么是视图: 视图其实就是一条查询sql语句,用于显示一个或多个表或其他视图中 ...

  3. BZOJ1037:[ZJOI2008]生日聚会Party(DP)

    Description 今天是hidadz小朋友的生日,她邀请了许多朋友来参加她的生日party.hidadz带着朋友们来到花园中,打算坐成一排玩游戏. 为了游戏不至于无聊,就座的方案应满足如下条件: ...

  4. 针对Restful风格参数传递的请求获取真实url

    昨天遇到这样一个问题,先简单介绍下. 业务场景 我们想要统计热点请求URL,进而进行分析优化 方案 通过过滤器获取到请求url(调用方法request.getservletpath),通过redis进 ...

  5. matlab中boxplot字体大小设置

    网上找到的:set(findobj(gca,'Type','text'),'FontSize',18) boxplot() uses the default axes labeling for the ...

  6. 报错Caused by: org.hibernate.AnnotationException: No identifier specified for entity:

    Caused by: org.hibernate.AnnotationException: No identifier specified for entity:. 原因: 1.没有给实体类ID 解决 ...

  7. CSU-ACM2018暑期训练7-贪心

    A:合并果子(贪心+优先队列) B:HDU 1789 Doing Homework again(非常经典的贪心) C:11572 - Unique Snowflakes(贪心,两指针滑动保存子段最大长 ...

  8. vue路由页面加载的几种方法~

    懒加载 (1)定义:懒加载也叫延迟加载,即在需要的时候进行加载,随用随载. (2)为什么需要懒加载: 在单页应用中,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要 ...

  9. direct path write 等待事件导致数据库hang

    同事反应十几分钟前数据库好像挂起了一会,让我排查数据库是否存在什么问题. 第一反应看当前数据库还是否有什么等待事件,结果有direct path write等待事件. 于是抓了问题时间段20分钟的AS ...

  10. java判断类型

    判断是否String:str.getClass().getName().equals("java.lang.String") 判断是否在且不为空:Object.hasKey(&qu ...