线程通信初始

简单认识一下线程通信

目录

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

线程通信定义

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

线程通信模型之一

释疑示例


案例

案例要求

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

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

案例简单实现

操作模版类

java 复制代码
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();
        }
    }
}

测试

java 复制代码
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();
    }
}

拓展

等待和唤醒API

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

参考视频

黑马磊哥


相关推荐
霸道流氓气质35 分钟前
Spring AI 多模态开发指南:图片理解与语音合成
java·人工智能·spring
en.en..40 分钟前
Linux mmap 内存映射深度解析:基于帧缓冲 /dev/fb0
java·服务器·前端
洋不写bug42 分钟前
链表补充练习,双链表的模拟实现
java·数据结构·链表·双链表·底层实现
后台模板学习1 小时前
用 IM 即时聊天项目一次讲清消息去重算法的踩坑与解决方案
java·数据库·spring
秋名RG1 小时前
2026/6/15 系统故障复盘与整改方案
java·架构
今天要早睡_1 小时前
C++ 核心语法速过:命名空间、引用、函数重载与 nullptr 深度解析
android·java·c++
南讯股份Nascent1 小时前
2026年CRM技术选型观察:当“数据打通“成为第一需求,电商CRM的架构价值在哪里
java·大数据·用户运营
心易行者1 小时前
Python自动化测试7步落地法:用python在线运行省掉90%环境配置时间
java·开发语言·人工智能·python·log4j·ai编程
霸道流氓气质2 小时前
Spring AI 技术细节:VectorStore 多库统一抽象
java·人工智能·spring
今天AI了吗2 小时前
Codex 配置自定义 AI API 完整指南:从零到一接入你的专属模型
java·人工智能·python·数据分析·embedding