Java多线程 notify 与notifyAll的区别

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方法, 因此程序最后也一直处于阻塞的状态 .

相关推荐

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值