1、源码

wait() notify() notifyAll()都是Object类中方法。源码如下所示:

    public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait() throws InterruptedException {
wait(0);
}

可以看到它们都是final native修饰的方法。

2、使用条件

首先我们需要明确的一点是wait() notify() notifyAll()都是需要在线程拥有对象锁的情况下使用

在没有对象锁的情况下使用会抛出异常。执行下面代码,会抛出 java.lang.IllegalMonitorStateException 异常

package com.test;

public class Test {
public static void main(String[] args){
try {
Object obj = new Object();
obj.wait();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}

3、作用

3.1 wait()方法的作用

wait()方法能够使当前线程停止,进入阻塞序列,等待被唤醒。

wait()方法被调用后,当前线程会立即释放持有的对象锁。其他线程可以通过竞争的方式获取该对象锁。

唤醒处于阻塞状态的线程,需要其他线程使用notify()或者notifyAll()方法。

3.2 notify()方法的作用

notify()方法能够唤醒处于阻塞状态(处于阻塞队列中)的线程。

需要注意的是调用一次notify()方法只能唤醒一个处于阻塞状态的线程。

而且调用notify()方法后,当前线程不会马上释放锁,被notify 的线程也不会马上获取该对象锁,而是需要等待当前线程执行完同步代码块。

3.3 notifyAll()方法的作用

notifyAll()方法能够唤醒正在等待同意共享资源的所有线程。

4、实例

直接上代码咯。

package com.test;

public class Test3 {

    class WaitThread implements Runnable{

        private Object lock;

        public WaitThread(Object lock) {
// TODO Auto-generated constructor stub
super();
this.lock = lock;
} @Override
public void run() {
// TODO Auto-generated method stub
try {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() +
" 即将进入阻塞状态 wait time = " + System.currentTimeMillis());
lock.wait();
System.out.println(Thread.currentThread().getName() +
" 结束阻塞状态 wait time = " + System.currentTimeMillis());
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
} class NotifyThread implements Runnable{ private Object lock; public NotifyThread(Object lock) {
// TODO Auto-generated constructor stub
super();
this.lock = lock;
} @Override
public void run() {
// TODO Auto-generated method stub
try {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() +
" 即将唤醒 notify time = " + System.currentTimeMillis());
lock.notify();
System.out.println(Thread.currentThread().getName() +
" 唤醒线程执行结束 notify time = " + System.currentTimeMillis());
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
} public static void main(String[] args){
try {
Object lock = new Object();
Test3 test3 = new Test3();
Thread waitThread = new Thread(test3.new WaitThread(lock));
waitThread.start();
Thread.sleep(3000);
Thread notifyThread = new Thread(test3.new NotifyThread(lock));
notifyThread.start();
} catch (Exception e) {
// TODO: handle exception
}
}
}

5、总结

1 wait() notify() notifyAll() 方法只能在线程拥有对象锁的时候调用

2 wait()方法调用后 当前线程会立即释放锁

3 notify() notifyAll()方法执行后 当前对象并不会立即释放锁,而是要等同步代码块执行完成后才能释放锁

4 notify()方法每次调用后只能唤醒处于阻塞队列中的一个线程,如果需要唤醒等待当前资源的所有线程需要使用notifyAll()方法

Java多线程编程——wait()和notify()、notifyAll()的更多相关文章

  1. java多线程的wait、notify/notifyAll区别

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

  2. Java多线程编程——进阶篇二

    一.线程的交互 a.线程交互的基础知识 线程交互知识点需要从java.lang.Object的类的三个方法来学习:    void notify()           唤醒在此对象监视器上等待的单个 ...

  3. Java多线程编程详解

    转自:http://programming.iteye.com/blog/158568 线程的同步 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Ja ...

  4. Java多线程编程的常见陷阱(转)

    Java多线程编程的常见陷阱 2009-06-16 13:48 killme2008 blogjava 字号:T | T 本文介绍了Java多线程编程中的常见陷阱,如在构造函数中启动线程,不完全的同步 ...

  5. Java多线程编程总结(精华)

    Java多线程编程总结 2007-05-17 11:21:59 标签:多线程 java 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http ...

  6. Java多线程编程核心技术

    Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...

  7. 《Java 多线程编程核心技术》- 笔记

    作为业务开发人员,能够在工作中用到的技术其实不多.虽然平时老是说什么,多线程,并发,注入,攻击!但是在实际工作中,这些东西不见得用得上.因为,我们用的框架已经把这些事做掉了. 比如web开发,外面有大 ...

  8. Java多线程编程核心技术(三)多线程通信

    线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...

  9. Java多线程编程实战指南(核心篇)读书笔记(三)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76686044冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

随机推荐

  1. [LeetCode] 27. Remove Element ☆

    Given an array and a value, remove all instances of that value in place and return the new length. D ...

  2. bzoj 2502 清理雪道 (有源汇上下界最小流)

    2502: 清理雪道 Time Limit: 10 Sec  Memory Limit: 128 MB Description        滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场 ...

  3. CF544 C 背包 DP

    n个人写m行代码,第i人写一行代码有a[i]个bug,问总bug数不超过b的不同方案数. 其实就是个背包,dp[i][j][k]代表前i个人写了j行代码用了k个bug限度,然后随便转移一下就好了 /* ...

  4. Jeson老师写的nginx切割脚本

    #Jeson #Email:jeson@iaskjob.com #变量定义:access.error日志文件列表 NGINX_LOG=(imoocc_com_access iaskjob_com er ...

  5. 重构改善既有代码设计--重构手法04:Replace Temp with Query (以查询取代临时变量)

    所谓的以查询取代临时变量:就是当你的程序以一个临时变量保存某一个表达式的运算效果.将这个表达式提炼到一个独立函数中.将这个临时变量的所有引用点替换为对新函数的调用.此后,新函数就可以被其他函数调用. ...

  6. 提高效率!15款最好的 Bug 跟踪应用程序

    当涉及到开发项目时,其中比较重要的事情是它需要某​​种形式的错误和问题跟踪工具来发现和解决问题,否则会浪费大量的时间. 此外,你总是要标签应用来标示那些悬而未决的问题,而这种分期执行的项目进度将帮助您 ...

  7. Js冒泡事件详解及阻止

    Js冒泡机制是指如果某元素定义了事件A,如click事件,如果触发了事件之后,没有阻止冒泡事件,那么事件将向父级元素传播,触发父类的click函数. 如下例所示: <html>     & ...

  8. [linux]linux下安装mysql

    1.安装g++$sudo apt-get install build-essential注:此命令会同时安装gcc和make2.安装cmake$sudo apt-get install cmake3. ...

  9. 【POJ】2142 The Balance 数论(扩展欧几里得算法)

    [题意]给定a,b,c,在天平左边放置若干重量a的砝码,在天平右边放置若干重量b的砝码,使得天平两端砝码差为c.设放置x个A砝码和y个B砝码,求x+y的最小值. [算法]数论(扩展欧几里德算法) [题 ...

  10. Traffic-Server配置(待补充和更新)

    Server 5.3.2 测试1.裸盘:remap.configmap http://192.168.227.131 http://192.168.227.131:8080 #traffic_serv ...