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. Alpha Scrum1

    Alpha Scrum1 牛肉面不要牛肉不要面 Alpha项目冲刺(团队作业5) 各个成员在 Alpha 阶段认领的任务 林志松:音乐网页前端页面编写,博客发布 吴沂章:博客编写 林锃寒:前端页面编写 ...

  2. 分享Spring Scheduled定时器的用法

    摘要:在coding中经常会用到定时器,指定每隔1个小时,或是每天凌晨2点执行一段代码段,若是使用java.util.Timer来做这种事情,未免重复造轮子.幸亏Spring中封装有定时器,而且非常好 ...

  3. 如何在Windows中安装GitHub

    1.使用Git 在Git官网下载Git安装包,双击开始安装即可.安装完毕之后,在Windows中会具有一个Git Bash命令行工具以及一个Git GUI客户端工具. 点击Download即可下载. ...

  4. 【转】九步学习python装饰器

    本篇日志来自:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 纯转,只字未改.只是为了学习一下装饰器.其实现在也是没有太看明白 ...

  5. Nginx卸载重装问题

    1.删除nginx,-purge包括配置文件 sudo apt-get --purge remove nginx   2.移除全部不使用的软件包 sudo apt-get autoremove   3 ...

  6. ORACLE查询删除重复记录

     比如现在有一人员表 (表名:peosons) 若想将姓名.身份证号.住址这三个字段完全相同的记录查询出来 复制代码 代码如下: select p1.*   from persons  p1,pers ...

  7. 批量解压Zip文件

    实现效果: 实现代码:

  8. Selenium基础知识(8大元素定位概说)

    1. By.name() 页面源码如下: [html] : <button id="gbqfba"aria-label="Google Search" n ...

  9. Nginx 作为静态资源服务器

    Nginx Windows 版本的启动停止,重新加载配置 启动 Windows版本下载解压后有一个nginx.exe可执行文件,双击启动. 启动后 浏览器访问http://127.0.0.1 可以看到 ...

  10. 智能门锁超低功耗:SI522(13.56芯片)替代MFRC522\FM17522

    SI522(超低功耗13.56M芯片)替代RC522 完全兼容 PIN对PIN,同时也替代FM17522. MF RC522 是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员.是 ...