简介

wait、notify、notifyAll是Java中3个与线程有关的方法,它们都是Object类中的方法。

其中,wait方法有3个重载形式:

1、wait()

2、wait(long timeout)

3、wait(long timeout, int nanos)

这5个方法都是final方法。其中,wait(long timeout)、notify()、notifyAll()都是native方法。

另外,3个wait方法均有InterruptedException抛出,而notify和notifyAll方法没有异常抛出。

这3类方法的语义大致如下所述:

wait

如果调用了某对象的wait方法,那么持有该对象的锁的线程会放弃对该对象的锁定,然后等待再次获得该对象的锁。

notify

如果调用了某对象的notify方法,那么某个在等待获得该对象的锁的线程会被唤醒继续执行。

notifyAll

与notify稍有不同的是,notifyAll方法会唤醒在该对象上等待的所有线程。

特别提醒的是,wait、notify、notifyAll方法都必须在同步方法或同步语句块内部调用。这是因为要调用这3类方法,必须让当前线程持有方法所属的对象的锁,否则就会抛出IllegalMonitorStateException。

例如,下面的代码是错误的,因为在调用对象a的wait()方法之前,当前线程没有持有对象a的锁:

public class A {

public void m() throws InterruptedException {

this.wait();

}

public static void main(String[] args) {

A a = new A();

try {

a.m();

} catch (Throwable t) {

t.printStackTrace();

}

}

}

运行上面的代码,必然抛出如下异常:

java.lang.IllegalMonitorStateException

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:485)

at A.m(A.java:4)

at A.main(A.java:10)

正确的写法,是给A类的m方法加上synchronized修饰符,这样,当执行到m方法内部的“this.wait()”语句时,当前线程已经持有了对象a的锁,调用它的wait()方法就不会抛出异常了。

有了这些知识点,我们来具体看一下这3类方法。

wait(long timeout)

该方法的声明语句如下:

public final native void wait() throws InterruptedException;

它的作用是:调用某对象的wait(long timeout)方法会造成当前线程放弃该对象的锁,转到等待状态,直到其它线程调用了该对象的notify()或notifyAll()方法,或者指定的时间(timeout)被耗尽。

该方法的参数timeout的单位是毫秒。值得注意的是,即便timeout参数所指定的时间被耗尽,当前线程也不是一定就会恢复执行,这要看时间耗尽时是否有其它线程持有该对象的锁。

参数timeout不能是负数,否则会抛出IllegalArgumentException。timeout为0时,表示无限等待,时间不会耗尽,只能等别的线程来唤醒自己。

wait()、wait(long timeout, int nanos)

这两个方法的声明语句如下:

public final void wait() throws InterruptedException {

wait(0);

}

public final void wait(long timeout, int nanos) throws InterruptedException {

if (timeout < 0)

throw new IllegalArgumentException(

“timeout value is negative”);

if (nanos < 0 || nanos > 999999)

throw new IllegalArgumentException(

“nanosecond timeout value out of range”);

if (nanos >= 500000 || (nanos != 0 && timeout == 0))

timeout++;

wait(timeout);

}

从代码上看,并结合wait(long timeout)的介绍,其逻辑意义就很明显了,不多做介绍。

notify()、notifyAll()

这两个方法的声明语句如下:

public final native void notify();

public final native void notifyAll();

notify和notifyAll的区别是,notifyAll会唤醒所有在某对象上等待的线程继续执行,但实际上,无论调用notify还是调用notifyAll,结果都只能有一个线程拿到锁并真的继续执行。

需要注意的是,当notify或notifyAll被调用成功后,被唤醒的线程实际上已经进入synchronized方法或代码块内部,这一点非常重要。

wait(...) notify() notifyAll()的更多相关文章

  1. java 多线程之wait(),notify,notifyAll(),yield()

    wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能.因为都个对像都 ...

  2. java中的wait(),notify(),notifyAll(),synchronized方法

    wait(),notify(),notifyAll()三个方法不是Thread的方法,而是Object的方法.意味着所有对象都有这三个方法,因为每个对象都有锁,所以自然也都有操作锁的方法了.这三个方法 ...

  3. java 多线程(wait/notify/notifyall)

    package com.example; public class App { /* wait\notify\notifyAll 都属于object的内置方法 * wait: 持有该对象的线程把该对象 ...

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

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

  5. 使用Object的wait,notify,notifyAll做线程调度

    我们知道java中的所有类的祖先都是Object,Object类有四个个方法wait(),wait(long timeout),notify(),notifyAll(),这四个方法可以用来做线程的调度 ...

  6. Java多线程之wait(),notify(),notifyAll()

    在多线程的情况下,因为同一进程的多个线程共享同一片存储空间,在带来方便的同一时候,也带来了訪问冲突这个严重的问题.Java语言提供了专门机制以解决这样的冲突,有效避免了同一个数据对象被多个线程同一时候 ...

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

    在多线程的情况下.因为多个线程与存储空间共享相同的过程,同时带来的便利.它也带来了访问冲突这个严重的问题. Java语言提供了一种特殊的机制来解决这类冲突,避免同一数据对象由多个线程在同一时间访问. ...

  8. Java多线程学习之wait、notify/notifyAll 详解

    1.wait().notify/notifyAll() 方法是Object的本地final方法,无法被重写. 2.wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized 关 ...

  9. 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型

    关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...

  10. Java多线程:wait(),notify(),notifyAll()

    1. wait(),notify(),notifyAll() 2. wait() 2.1. wait() 2.2. wait(long timeout) 2.3. wait(long timeout, ...

随机推荐

  1. MapReduce的流程

    1. Inputformat会从job的INPUT_DIR目录下读入待处理的文件,检查输入的有效性并将文件切分成InputSplit列表.Job实例可以通过setInputFormatClass(Cl ...

  2. hadoop安装详解

    1.hadoop简介 Hadoop是Apache软件基金会旗下的一个开源分布式计算平台.以Hadoop分布式文件系统(HDFS,Hadoop Distributed Filesystem)和MapRe ...

  3. Thread学习

    1.定义 2.作用 3.和进程的比较 4.多线程(multithreading)的优点和缺陷 5.调度(scheduling) 6.线程相关概念 定义 线程就是最小的可编程指令序列,是进程的子集.一个 ...

  4. BZOJ 1934: [Shoi2007]Vote 善意的投票 最小割

    1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnl ...

  5. [Bootstrap] 7. Working Herader

    <header class="navbar navbar-default navbar-static-top"> <div class="contain ...

  6. wcf-1

    1.WCF是什么? WindowsCommunication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,它是.NET框架的一部分,由.NET Framework 3. ...

  7. Docker容器案例:应用 Mysql

    原创 杜亦舒   前阶段体验 Mysql 的新版本 5.7.13,由于机器里已经有 Mysql了,再安装另一个版本会有一些麻烦,为了简单,便使用 Docker 容器来安装 可能有人会认为没必要,在一台 ...

  8. 数据库性能测试---前阿里数据库团队资深DBA杨奇龙

    杨奇龙 前阿里数据库团队资深DBA 主要负责淘宝业务线,经历多次11.11,有海量业务访问DB架构设计经验. 目前就职于有赞科技DBA,负责数据库运维工作,熟悉MySQL 性能优化,故障诊断,性能压测 ...

  9. Hibernate连接MySQL数据库乱码相关问题

    1.查看MySQL字符编码 >show variables like 'character%'; #执行编码显示 其中character_set_client,character_set_res ...

  10. PHP免费API调用,使用(CURL)

    <?phpclass GetApiModel{//获取第三方API //获取身份证信息 //返回json /*{ "errNum": 0, "retMsg" ...