线程通信初始

简单认识一下线程通信

目录

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

线程通信定义

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

线程通信模型之一

释疑示例


案例

案例要求

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

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

参考视频

黑马磊哥


相关推荐
JH307326 分钟前
Java Stream API 在企业开发中的实战心得:高效、优雅的数据处理
java·开发语言·oracle
九月十九3 小时前
java使用aspose读取word里的图片
java·word
一 乐4 小时前
民宿|基于java的民宿推荐系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·源码
爱记录的小磊4 小时前
java-selenium自动化快速入门
java·selenium·自动化
鹏码纵横4 小时前
已解决:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 异常的正确解决方法,亲测有效!!!
java·python·mysql
weixin_985432114 小时前
Spring Boot 中的 @ConditionalOnBean 注解详解
java·spring boot·后端
Mr Aokey4 小时前
Java UDP套接字编程:高效实时通信的实战应用与核心类解析
java·java-ee
冬天vs不冷4 小时前
Java分层开发必知:PO、BO、DTO、VO、POJO概念详解
java·开发语言
hong_zc4 小时前
Java 文件操作与IO流
java·文件操作·io 流