3 线程等待与唤醒 wait/notify(notifyAll)

 

Synchronized 结合 Java Object 对象中的wait,notify,notifyAll
 学习synchronized时候 ,发现被阻塞的线程什么时候被唤醒,取决于获得锁的线程什么时候执行完同步代码块并且释放锁。那怎么做到显示控制呢?我们就需要借助一个信号机制 : 在 Object 对 象 中 , 提 供 了wait/notify/notifyall,可以用于控制线程的状态
 
wait/notify/notifyall 基本概念
wait:表示持有对象锁的线程 A 准备释放对象锁权限,释放 cpu 资源并进入等待状态
notify:表示持有对象锁的线程 A 准备释放对象锁权限,通知 jvm 唤醒某个竞争该对象锁的线程X 。线 程 A  synchronized 代码执行结束并且释放了锁之后,线程 X 直接获得对象锁权限,等待cpu时间脆片来执行,其他竞争线程继续等待(即使线程 X 同步完毕,释放对象锁,其他竞争线程仍然等待,直至有新的 notify ,notifyAll 被调用)。
notifyAll:notifyall 和 notify 的区别在于,notifyAll 会唤醒所有竞争同一个对象锁的所有线程,当已经获得锁的线程A 释放锁之后,所有被唤醒的线程都有可能获得对象锁权限
 
需要注意的是:三个方法都必须在 synchronized 同步关键字 所 限 定 的 作 用 域 中 调 用 , 否 则 会 报 错java.lang.IllegalMonitorStateException ,意思是因为没有同步,所以线程对对象锁的状态是不确定的,不能调用这些方法。另外,通过同步机制来确保线程从 wait 方法返回时能够感知到感知到 notify 线程对变量做出的修改
 
 
wait/notify 的基本使用
参见源码

 

 代码示例:持有同一把锁

public class ThreadA extends Thread{

    private Object lock;
    public ThreadA(Object lock) {
        this.lock = lock;
    }
    @Override
    public void run() {
        synchronized (lock){
            System.out.println("start ThreadA");
            try {
                lock.wait(); //实现线程的阻塞
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("end ThreadA");
        }
    }
}
public class ThreadB extends Thread{
private Object lock;

public ThreadB(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock){
System.out.println("start ThreadB");
lock.notify(); //唤醒被阻塞的线程 该线程执行完,唤醒的线程拿到时间片开始执行
System.out.println("end ThreadB");
}
}
}
public class WaitNotifyDemo {

    public static void main(String[] args) {
        Object lock=new Object();
        ThreadA threadA=new ThreadA(lock);
        threadA.start();
        ThreadB threadB=new ThreadB(lock);
        threadB.start();
    }
}

运行结果:  

start ThreadA
start ThreadB
end ThreadB
end ThreadA
 
 

 

 

注意:jdk的解释中,说wait()的作用是让“当前线程”等待,而“当前线程”是指正在cpu上运行的线程!

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2020-02-03 16:50  LPJのBLOG  Views(448)  Comments(0)    收藏  举报