文章目录
notify 与notifyAll的区别
如下的代码, 首先演示了notifyAll 来唤醒全部的线程.
创建了两个线程A和B. 分别去获得锁, 并且调用wait方法释放锁.
紧接着 线程C 调用了notifyAll方法, 来唤醒 处于wait状态的所有线程.
同时,为了保证线程的执行顺序, 即为了保证调用唤醒notifyAll方法的时候, 所有的线程, 都是处于wait状态, 在启动了线程A和B之后, 启动线程c之前, 调用了sleep方法来保证线程执行顺序.
package com.thread.threadobjectclasscommonmethods;
/**
* 类名称:WaitNotifyAll
* 类描述: 3个线程 线程1 和线程2 先被阻塞 线程3 去唤醒他们
* start 先执行, 不代表线程先启动
* @author: https://javaweixin6.blog.csdn.net/
* 创建时间:2020/8/29 15:42
* Version 1.0
*/
public class WaitNotifyAll implements Runnable{
private static final Object resource = new Object();
public static void main(String[] args) {
Runnable runnable = new WaitNotifyAll();
Thread threadA = new Thread(runnable);
Thread threadB = new Thread(runnable);
Thread threadC = new Thread(new Runnable() {
@Override
public void run() {
synchronized (resource) {
resource.notifyAll();
//resource.notify();
System.out.println(Thread.currentThread().getName() + " 执行了notifyAll ");
}
}
});
threadA.setName("A");
threadA.start();
threadB.setName("B");
threadB.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadC.setName("C");
threadC.start();
}
@Override
public void run() {
synchronized (resource) {
//获得了锁的资源
System.out.println(Thread.currentThread().getName()+ " got resource lock ");
try {
//即将释放锁
System.out.println(Thread.currentThread().getName()+" will release lock ");
resource.wait();
//重新获得锁 即将运行结束
System.out.println(Thread.currentThread().getName()+" waiting to end ");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行程序, 控制台打印如下 . 与分析的一致, 线程a和b 分别的获得锁资源, 释放锁, 并且进入了wait的阻塞状态 . 之后线程c启动, 调用了notifyAll方法. 线程a和b都被唤醒, 完成了后续的方法, 结束了线程.
而如果线程c调用的是notify方法, 那么结果如下所示, 只会唤醒一个线程. 线程A被唤醒, 而线程B一直没有被唤醒, 控制台的红灯也一直亮着, 说明处于阻塞状态.
而如果在执行线程c之前, 没有调用sleep方法, 那么出现的现象如控制台所示, 线程a执行了之后, 紧接着线程c就执行了, 而不是按照start方法的顺序, 线程b先去执行的.
导致的后果就是线程c执行notifyAll方法的时候, 由于线程b还没有执行wait方法, 因此程序最后也一直处于阻塞的状态 .