多线程之线程通信

多线程之线程通信

线程通信就是当多个线程共同操作共享资源时,线程间通过某种方式互相告知自己的状态,以相互协调,避免无效的资源争抢。

常见模式:生产者与消费者模型

  • 生产者线程负责生成数据
  • 消费者线程负责消费生产者生成的数据
  • 注意:生产者生产完数据后应该让自己等待,通知其他消费者消费;消费者消费完数据之后应该让自己等待,同时通知生产者生成。

如图所示的案例,有3个厨师(生产者线程),两个顾客(消费者线程)

在这里插入图片描述

案例思路如下:

1.先确定在这个案例中,什么是共享数据?
	答:这里案例中桌子是共享数据,因为厨师和顾客都需要对桌子上的包子进行操作。

2.再确定有那几条线程?哪个是生产者,哪个是消费者?
	答:厨师是生产者线程,3条生产者线程; 
	   顾客是消费者线程,2条消费者线程
	   
3.什么时候将哪一个线程设置为什么状态
	生产者线程(厨师)放包子:
		 1)先判断是否有包子
		 2)没有包子时,厨师开始做包子, 做完之后把别人唤醒,然后让自己等待
		 3)有包子时,不做包子了,直接唤醒别人、然后让自己等待
		 	
	消费者线程(顾客)吃包子:
		 1)先判断是否有包子
		 2)有包子时,顾客开始吃包子, 吃完之后把别人唤醒,然后让自己等待
		 3)没有包子时,不吃包子了,直接唤醒别人、然后让自己等待

代码如下:

//先写桌子类
public class Desk {
    private List<String> list = new ArrayList<>();

    // 放1个包子的方法
    // 厨师1 厨师2 厨师3
    public synchronized void put() {
        try {
            String name = Thread.currentThread().getName();
            // 判断是否有包子。
            if(list.size() == 0){
                list.add(name + "做的肉包子");
                System.out.println(name + "做了一个肉包子~~");
                Thread.sleep(2000);

                // 唤醒别人, 等待自己
                this.notifyAll();
                this.wait();
            }else {
                // 有包子了,不做了。
                // 唤醒别人, 等待自己
                this.notifyAll();
                this.wait();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 吃货1 吃货2
    public synchronized void get() {
        try {
            String name = Thread.currentThread().getName();
            if(list.size() == 1){
                // 有包子,吃了
                System.out.println(name  + "吃了:" + list.get(0));
                list.clear();
                Thread.sleep(1000);
                this.notifyAll();
                this.wait();
            }else {
                // 没有包子
                this.notifyAll();
                this.wait();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//再写测试类,在测试类中,创建3个厨师线程对象,再创建2个顾客对象,并启动所有线程
public class ThreadTest {
    public static void main(String[] args) {
        //   需求:3个生产者线程,负责生产包子,每个线程每次只能生产1个包子放在桌子上
        //      2个消费者线程负责吃包子,每人每次只能从桌子上拿1个包子吃。
        Desk desk  = new Desk();

        // 创建3个生产者线程(3个厨师)
        new Thread(() -> {
            while (true) {
                desk.put();
            }
        }, "厨师1").start();

        new Thread(() -> {
            while (true) {
                desk.put();
            }
        }, "厨师2").start();

        new Thread(() -> {
            while (true) {
                desk.put();
            }
        }, "厨师3").start();

        // 创建2个消费者线程(2个吃货)
        new Thread(() -> {
            while (true) {
                desk.get();
            }
        }, "吃货1").start();

        new Thread(() -> {
            while (true) {
                desk.get();
            }
        }, "吃货2").start();
    }
}
//执行上面代码,运行结果如下:会发现多个线程相互协调执行,避免无效的资源挣抢。
厨师1做了一个肉包子~~
吃货2吃了:厨师1做的肉包子
厨师3做了一个肉包子~~
吃货2吃了:厨师3做的肉包子
厨师1做了一个肉包子~~
吃货1吃了:厨师1做的肉包子
厨师2做了一个肉包子~~
吃货2吃了:厨师2做的肉包子
厨师3做了一个肉包子~~
吃货1吃了:厨师3做的肉包子
  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值