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

  1. Object类中wait代餐方法和notifyAll方法和线程间通信

    Object类中wait代餐方法和notifyAll方法 package com.yang.Test.ThreadStudy; import lombok.SneakyThrows; /** * 进入 ...

  2. 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 ...

  3. JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别

    JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别   关于获取类的字段有两种方式:getFields()和getDeclaredFields().我们先来 ...

  4. Object类中wait带参方法和notifyAll方法和线程间通信

    notifyAll方法: 进入到Timed_Waiting(计时等待)状态有两种方式: 1.sleep(long m)方法,在毫秒值结束之后,线程睡醒,进入到Runnable或BLocked状态 2. ...

  5. Java Thread中,run方法和start方法的区别

     两种方法的区别: 1.start方法 用 start方法来启动线程,是真正实现了多线程, 通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦 ...

  6. [转]JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别

    关于获取类的字段有两种方式:getFields()和getDeclaredFields().我们先来看看这两者的区别吧: getFields():获得某个类的所有的公共(public)的字段,包括父类 ...

  7. java.util.Scanner中hasNext()方法和next()方法的区别

    先说结论: 两者均根据空格划分数据 两者在没有数据输入时均会等待输入 next()方法会将空格划分的数据依次输出,运行一次,输出一个 hasNext()方法会跟着next()方法移动,当前数据不为空, ...

  8. Java中Scanner中nextLine()方法和next()方法的区别

    https://blog.csdn.net/hello_word2/article/details/54895106

  9. 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 ...

随机推荐

  1. vue_源码 原理 剖析

    相关基础知识点 // 可以让 任意函数/方法 成功临时指定成对象的方法进行调用 - call/apply // 1. 根据伪数组生成 真数组 const lis = document.getEleme ...

  2. IEnumerable、IEnumerator、ICollection、IList、List的继承关系及简单使用

    IEnumerable和IEnumerable<T>接口在.NET中是非常重要的接口,它允许开发人员定义foreach语句功能的实现并支持非泛型方法的简单的迭代,IEnumerable和I ...

  3. vs代码模板制作

    VS2008代码模板制作 一,类模板制作: 路径:C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplate ...

  4. MGR

    单主模式 参数修改 server_id=1 gtid_mode=ON enforce_gtid_consistency=ON binlog_checksum=NONE log_bin=binlog l ...

  5. flask读书笔记

    学习flask的一个很好的网站:http://www.pythondoc.com/flask-mega-tutorial/helloworld.html ======================= ...

  6. 《Redis 使用规范》

    一:Redis 概述 - Redis 是内存级别的数据库,在一台普通电脑上,Redis 3.X 便可以读取 10 万个键值对(现在的Redis官方版本已经更新到了5.X,性能会更好). 二:关于Red ...

  7. (Linux)CentOS7下安装JDK 1.8

    参考:http://www.cnblogs.com/sxdcgaq8080/p/7492426.html 1.首先查看CentOS7是否有自带的JDK ,一般Linux会自动下载安装Open JDK ...

  8. php 数据库乱码。。。php 移动临时文件

    数据库乱码,三个位置 处理好不会乱码 第一前台,传到后台: 第二后台,传到数据库: 第三数据库,存入数据库: 详解  https://www.cnblogs.com/zhoujinyi/p/46188 ...

  9. org.springframework.boot.web.server.WebServerException: Unable to create tempDir. java.io.tmpdir is set to C:\Users\ADMINI~1\AppData\Local\Temp\2\

    问题原因:springboot创建临时文件找不到对应的目录 解决办法:1. 重新指定临时文件位置  java -Djava.io.tempdir=D:/tmpdir -jar -my_project. ...

  10. 安卓demo

    https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/README-CN.md