线程通信初始

简单认识一下线程通信

目录

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

线程通信定义

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

线程通信模型之一

释疑示例


案例

案例要求

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

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

参考视频

黑马磊哥


相关推荐
lj90772264438 分钟前
Dockerfile部署xxljob
java·docker
多则惑少则明1 小时前
idea 编辑器常用插件集合
java·编辑器·intellij-idea
BLUcoding1 小时前
RabbitMQ08_保证消息可靠性
java·rabbitmq
MogulNemenis1 小时前
力扣415周赛
java·数据结构·算法·leetcode
ai安歌1 小时前
【JavaWeb】利用IDEA2024+tomcat10配置web6.0版本搭建JavaWeb开发项目
java·开发语言·后端·tomcat·web·intellij idea
2407-2 shw1 小时前
weblogic CVE-2018-2894 靶场攻略
java·运维·服务器·安全·weblogic
尘浮生1 小时前
Java项目实战II基于Java+Spring Boot+MySQL的作业管理系统设计与实现(源码+数据库+文档)
java·开发语言·数据库·spring boot·后端·mysql·spring
lizhou8282 小时前
win10下使用docker、k8s部署java应用
java·docker·kubernetes
程序员阿鹏2 小时前
ArrayList 与 LinkedList 的区别?
java·开发语言·后端·eclipse·intellij-idea
18你磊哥2 小时前
java重点学习-JVM类加载器+垃圾回收
java·jvm