线程通信的实现方式

背景

解决多线程环境下,各个线程间的通信问题

应用场景

生产者和消费者问题

核心实现方式

方法说明
wait()线程会一直等待,直到其他线程通知,与sleep不同,wait()会释放锁
wait(long timeout)指定等待的毫秒数
notify()唤醒一个处于等待状态的线程
notifyAll()唤醒同一个对象上所有调用wait()方法的线程,优先级高的线程,优先调度

注意:上述方法均是Object类的方法,只能在 同步方法 或者 同步代码块 中使用,否则会抛出 IIIegalMonitorStateException

实现方式

  • 管程法
  • 信号灯法

举例说明

1、管程法实现

场景:商家生产蛋糕,将蛋糕放到柜子里,消费者购买蛋糕,从柜子里取出蛋糕
涉及通信问题:商家生产了蛋糕,就可以通知消费者过来购买蛋糕;消费者买空了柜子里的蛋糕,就应该通知商家生产
代码实现

package com.wei.thread.commute;

/**
 * @author: wei
 * @date 2022/5/4 21:57
 * 说明:生产者与消费者通信问题测试
 **/
public class TestProducerConsumer {

    public static void main(String[] args) {
        IceBox iceBox = new IceBox();
        Shop shop = new Shop(iceBox);
        Consumer consumer = new Consumer(iceBox);
        shop.start();
        consumer.start();
    }
}

// 商家
class Shop extends Thread {
    IceBox iceBox;

    public Shop(IceBox iceBox) {
        this.iceBox = iceBox;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("商家生产蛋糕,编号:" + i);
            iceBox.push(new Cake(i));
        }

    }

}

// 消费者
class Consumer extends Thread {
    IceBox iceBox;

    public Consumer(IceBox iceBox) {
        this.iceBox = iceBox;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            Cake cake = iceBox.pop();
            System.out.println("取到蛋糕,编号为:" + cake.id);
        }

    }
}

// 蛋糕
class Cake {
    int id;

    public Cake(int id) {
        this.id = id;
    }
}


// 冷藏柜
class IceBox {

    // 冰柜大小, 可以放10个蛋糕
    Cake[] cakes = new Cake[10];
    int count = 0;

    public synchronized void push(Cake cake) {
        if (count == cakes.length) {
            // 停止生产,等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 将蛋糕放入冰柜,并通知消费者过来购买
        cakes[count] = cake;
        count++;
        this.notifyAll();
    }

    public synchronized Cake pop() {
        Cake cake = null;

        if (count <= 0) {
            // 没有蛋糕了,通知商家生产,并在此等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        cake = cakes[--count];
        this.notifyAll();
        return cake;
    }
}

2、信号灯法实现

场景:
涉及通信问题:
代码实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值