wait(...) notify() notifyAll()
简介
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()的更多相关文章
- java 多线程之wait(),notify,notifyAll(),yield()
wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能.因为都个对像都 ...
- java中的wait(),notify(),notifyAll(),synchronized方法
wait(),notify(),notifyAll()三个方法不是Thread的方法,而是Object的方法.意味着所有对象都有这三个方法,因为每个对象都有锁,所以自然也都有操作锁的方法了.这三个方法 ...
- java 多线程(wait/notify/notifyall)
package com.example; public class App { /* wait\notify\notifyAll 都属于object的内置方法 * wait: 持有该对象的线程把该对象 ...
- Java多线程8:wait()和notify()/notifyAll()
轮询 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A线程做int型变量i的累加操作,B线程等待i到了10000就打印出i,怎么处 ...
- 使用Object的wait,notify,notifyAll做线程调度
我们知道java中的所有类的祖先都是Object,Object类有四个个方法wait(),wait(long timeout),notify(),notifyAll(),这四个方法可以用来做线程的调度 ...
- Java多线程之wait(),notify(),notifyAll()
在多线程的情况下,因为同一进程的多个线程共享同一片存储空间,在带来方便的同一时候,也带来了訪问冲突这个严重的问题.Java语言提供了专门机制以解决这样的冲突,有效避免了同一个数据对象被多个线程同一时候 ...
- Java多线程的wait(),notify(),notifyAll()
在多线程的情况下.因为多个线程与存储空间共享相同的过程,同时带来的便利.它也带来了访问冲突这个严重的问题. Java语言提供了一种特殊的机制来解决这类冲突,避免同一数据对象由多个线程在同一时间访问. ...
- Java多线程学习之wait、notify/notifyAll 详解
1.wait().notify/notifyAll() 方法是Object的本地final方法,无法被重写. 2.wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized 关 ...
- 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型
关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...
- Java多线程:wait(),notify(),notifyAll()
1. wait(),notify(),notifyAll() 2. wait() 2.1. wait() 2.2. wait(long timeout) 2.3. wait(long timeout, ...
随机推荐
- The Woman in Red Is Seen as a Threat by Other Wom
The Woman in Red Is Seen as a Threat by Other Wom In the 1939 film classic The Women, much is made o ...
- 【转】与BT下载相关的概念
1. DHT DHT全称叫分布式哈希表(Distributed Hash Table),是一种分布式存储方法.在不需要服务器的情况下,每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整 ...
- HubbleDotNet 学习之路
1.创建后台任务实现自动同步更新表数据.打开工具后点击“management”选项卡,选择“task scheduler management”,在弹出的窗口中点击右侧的"add" ...
- poj 1904 King's Quest tarjan求二分图的所有可选最大匹配边
因为是完美匹配,所以每个点都已经匹配了,那么如果要选择一条别的边,增光路的最后必定找到原来所匹配的点,加上匹配的边,那么就是一个环.所以可选边在一个强连通分量里. #include <iostr ...
- C#_数据库交互_SqlHelper
using System; using System.Collections.Generic; using System.Text; using System.Data.SqlClient; usin ...
- 浅谈iOS中的视图优化
引言: 让我们来思考几个问题,你开发过的产品,它还有可以优化的地方吗?能增加它的帧率吗?能减少多余的CPU计算吗?是不是存在多余的GPU渲染?业务这点工作量对于越来越强大的设备面前显得微不足道,但作为 ...
- ListVIew中插入view
public class MainActivity extends Activity { private ListView listview; private List<String> d ...
- Android_baseComponentExample
xml布局文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns ...
- multiple build commands for output file
在项目中 我们经常会碰到图片这方面的警告 虽然不影响运行 但是警告太多了也不是很好 其中 图片方面遇到的警告以下面的警告偏多:multiple build commands for output ...
- HeaderTemplate
前台代码: <asp:Repeater ID="rptList" runat="server" onitemdatabound="doSomet ...