• 线程通信初始


    简单认识一下线程通信

    :线程通信 前提是 线程安全

    线程通信定义

    当多个线程共同操作共享的资源时,线程间通过某种方式互相告知自己的状态,以相互协调或完成某一项任务,并避免无效的资源争夺

    线程通信模型之一

      
    在这里插入图片描述
      

    释疑示例

      
    在这里插入图片描述
      


    案例

    案例要求

    3个生产者线程,负责生产包子,每个线程每次只能生产1个包子放在桌子上

    2个消费者线程负责吃包子,每人每次只能从桌子上拿1个包子吃

    案例简单实现

    操作模版类

    package com.xie.thread.communication;
    
    import java.util.ArrayList;
    import java.util.List;
    /**
     * 容器--桌子,同时也是操作对象模版类   注:当前锁对象用this关键字来指定
     * */
    public class Desk {
        private List<String> list = new ArrayList<>();
        /**
         * 放包子方法 操作对象:厨师1 厨师1 厨师3
         * */
        public synchronized void put() {
            // 获取当前执行的线程名
            String name = Thread.currentThread().getName();
            try {
                // 判断集合中是否有元素(包子)
                if (list.size() == 0) {
                    list.add(name + "做的肉包子");
                    System.out.println(name + "做了一个肉包子~~");
                    // 模拟工作耗时,等待时间
                    Thread.sleep(2000);
                    // 唤醒别人,等待自己
                    this.notifyAll();
                    this.wait();
                }else {
                    // 发现容器中有元素(包子)
                    // 唤醒别人,等待自己
                    this.notifyAll();
                    this.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        /**
         * 取(或吃)包子方法 操作对象:吃货1 吃货2
         * */
        public synchronized void get() {
            // 获取当前执行的线程名
            String name = Thread.currentThread().getName();
            try {
                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 (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    测试

    package com.xie.thread.communication;
    
    /**
     * 线程通信---消费者与生产者案例   注:下面的5个线程共用同一把锁!!!
     *
     * 案例要求:
     * 3个生产者线程,负责生产包子,每个线程每次只能生产1个包子放在桌子上
     * 2个消费者线程负责吃包子,每人每次只能从桌子上拿1个包子吃
     * */
    public class ThreadTest {
        public static void main(String[] args) {
            /**创建操作对象*/
            Desk desk = new Desk();
            /**
             * 创建三个消费者线程,匿名内部类方式创建
             * */
            new Thread(() -> {
                while (true) {
                        desk.put();
                }
            }, "厨师1").start();
    
            new Thread(() -> {
                while (true) {
                    desk.put();
                }
            }, "厨师2").start();
    
            new Thread(() -> {
                while (true) {
                    desk.put();
                }
            }, "厨师3").start();
    
            /**
             * 创建两个生产者线程,匿名内部类方式创建
             * */
            new Thread(() -> {
                while (true) {
                    desk.get();
                }
            }, "吃货1").start();
    
            new Thread(() -> {
                while (true) {
                    desk.get();
                }
            }, "吃货2").start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    拓展

    等待和唤醒API

      
    在这里插入图片描述
      

    :上述方法应该使用 当前同步锁对象 进行调用

    参考视频

    黑马磊哥


  • 相关阅读:
    animate动画库的使用步骤
    计算机毕业设计ssm+vue基本微信小程序的好物推荐分享系统
    【JAVASE系列】06_继承,多态与final
    BEiT-3论文阅读笔记
    第五章 Jest进行前端单元测试
    cv_for_nlp
    SpringCloud简单的远程调用Demo
    Redis实战精讲(3)
    体验方法的引用
    转铁蛋白修饰纳米载体(纳米颗粒,介孔硅,四氧化三铁,二氧化硅等)
  • 原文地址:https://blog.csdn.net/m0_69604107/article/details/133549288