多线程 ---- 线程的通信

wait(), notify(), notifyAll() 方法

(1) 语法上: 都必须在 synchronized 修饰的代码块中, 如果没在, 就会抛出异常.
(2) 作用: 由于在 synchronized 修饰的代码块中, 所以线程一定是运行态, 且已经成功获取到对象锁.

在这里插入图片描述
在这里插入图片描述

下面举一个面包店的例子来进行说明 线程间的通信

package Java05_23;

// 假设面包店有面包师傅有5个, 可以一直生产面包, 每次生产3个
// 假设面包店有20个消费者, 可以一直消费面包, 每次消费1个
// 假设面包店库存上限是100个, 下限是0

public class SignalTest {

    // 库存
    private static int SUM;

    public static void main(String[] args) {
        // 5个面包师傅, 同时启动
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        while (true) {
                           synchronized (SignalTest.class) {
                                if (SUM + 3 > 100) {
                                    SignalTest.class.wait();
                                } else {
                                    SUM += 3;
                                    System.out.println(Thread.currentThread().getName() + "生产了面包, 库存:" + SUM);
                                    Thread.sleep(500);
                                    SignalTest.class.notify();
                                }
                           }
                           Thread.sleep(200);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "面包师傅[" + i + "] 号").start();
        }
        // 20个消费者, 同时启动
        for (int i = 0; i < 20; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        while (true) {
                            synchronized (SignalTest.class) {
                                if (SUM == 0) {
                                    SignalTest.class.wait();
                                } else {
                                    SUM--;
                                    System.out.println(Thread.currentThread().getName() + "消费了面包, 库存:" + SUM);
                                    Thread.sleep(500);
                                    SignalTest.class.notify(); // 随机通知一个 wait 方法阻塞的线程
//                                    SignalTest.class.notifyAll(); // 随机通知全部 wait 方法阻塞的线程
                                }
                            }
                            Thread.sleep(200);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "消费者[" + i + "] 号").start();
        }
    }
}

在这里插入图片描述
在这里插入图片描述
画图来详细描述一下这个过程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
再在生产者的代码中分析一下
在这里插入图片描述
wait 和 sleep 的对比

实质上, wait 和 sleep 是没有任何可比性的, 一个是用于线程间的通信的, 一个是让线程阻塞一段时间, 唯一的相同点就是可以让线程放弃执行一段时间.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值