线程间通信方式

2023-11-13

参考视频

实现一个场景

三个线程分别交替打印A、B、C,打印100次。

基于synchronized 锁的实现方式

public class test {

    private static Integer num = 0;
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (num < 100){
                    synchronized (num){
                        if (num%3==0&&num<=99){
                            System.out.println("A");
                            num++;
                        }
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (num < 100){
                    synchronized (num){
                        if (num%3==1&&num<=99){
                            System.out.println("B");
                            num++;
                        }
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (num < 100){
                    synchronized (num){
                        if (num%3==2&&num<=99){
                            System.out.println("C");
                            num++;
                        }
                    }
                }
            }
        }).start();

    }
}

基于Lock锁的Condition实现线程通信

package leetcode.leetcode11;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class test06 {

    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Condition conditionA = lock.newCondition();
        Condition conditionB = lock.newCondition();
        Condition conditionC = lock.newCondition();

        new Thread(new Runnable() {
            @Override
            public void run() {
                int a = 0;

                while (a<34){
                    lock.lock();
                    a++;
                    System.out.println("A");
                    conditionB.signal();

                    try {
                        conditionA.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.unlock();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                int a = 0;
                while (a<33){
                    lock.lock();
                    a++;
                    System.out.println("B");
                    conditionC.signal();
                    try {
                        conditionB.await();
                        if (a==33) conditionC.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.unlock();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                int a = 0;
                while (a<33){
                    a++;
                    lock.lock();
                    System.out.println("C");
                    conditionA.signal();
                    try {
                        conditionC.await();
                        if (a==33) conditionA.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.unlock();
                }
            }
        }).start();
    }

}

注意这里面还是需要注意一下的,比如实现打印完成之后线程结束,这里面就要进行if判断了if (a==33) conditionA.signal();因为如果不判断的话第一个线程执行完之后唤醒第二个,第二个执行完结束了,没有办法唤醒第三个等待的线程了。

对第二种方式进行重构优化

package leetcode.leetcode11;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class test06 {

    static class Runner implements Runnable{
        ReentrantLock lock;
        Condition now_condition;
        Condition next_condition;
        int num ;
        String ss;

        int a = 0;

        @Override
        public void run() {
            while (a<num){
                lock.lock();
                System.out.println(ss);
                a++;
                next_condition.signal();
                try {
                    now_condition.await();
                    if (a==33) next_condition.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                lock.unlock();
            }
        }

        public Runner(ReentrantLock lock, Condition now_condition, Condition next_condition, int num, String ss) {
            this.lock = lock;
            this.now_condition = now_condition;
            this.next_condition = next_condition;
            this.num = num;
            this.ss = ss;
        }
    }
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        Condition conditionA = lock.newCondition();
        Condition conditionB = lock.newCondition();
        Condition conditionC = lock.newCondition();

        Thread t1 = new Thread(new Runner(lock,conditionA,conditionB,34,"A"));
        Thread t2 = new Thread(new Runner(lock,conditionB,conditionC,33,"B"));
        Thread t3 = new Thread(new Runner(lock,conditionC,conditionA,33,"C"));

        t1.start();
        t2.start();
        t3.start();
    }

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线程间通信方式 的相关文章

  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • 如何默认将 Maven 插件附加到阶段?

    我有一个 Maven 插件应该在编译阶段运行 所以在项目中consumes我的插件 我必须做这样的事情
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • Java - 将节点添加到列表的末尾?

    这是我所拥有的 public class Node Object data Node next Node Object data Node next this data data this next next public Object g
  • JAXb、Hibernate 和 beans

    目前我正在开发一个使用 Spring Web 服务 hibernate 和 JAXb 的项目 1 我已经使用IDE hibernate代码生成 生成了hibernate bean 2 另外 我已经使用maven编译器生成了jaxb bean
  • INSERT..RETURNING 在 JOOQ 中不起作用

    我有一个 MariaDB 数据库 我正在尝试在表中插入一行users 它有一个生成的id我想在插入后得到它 我见过this http www jooq org doc 3 8 manual sql building sql statemen
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • 多个 Maven 配置文件激活多个 Spring 配置文件

    我想在 Maven 中构建一个环境 在其中我想根据哪些 Maven 配置文件处于活动状态来累积激活多个 spring 配置文件 目前我的 pom xml 的相关部分如下所示
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • 路径中 File.separator 和斜杠之间的区别

    使用有什么区别File separator和一个正常的 在 Java 路径字符串中 与双反斜杠相反 平台独立性似乎不是原因 因为两个版本都可以在 Windows 和 Unix 下运行 public class SlashTest Test
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 如何为俚语和表情符号构建正则表达式 (regex)

    我需要构建一个正则表达式来匹配俚语 即 lol lmao imo 等 和表情符号 即 P 等 我按照以下示例进行操作http www coderanch com t 497238 java java Regular Expression D
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 如何在 javadoc 中使用“<”和“>”而不进行格式化?

    如果我写
  • Java列表的线程安全

    我有一个列表 它将在线程安全上下文或非线程安全上下文中使用 究竟会是哪一个 无法提前确定 在这种特殊情况下 每当列表进入非线程安全上下文时 我都会使用它来包装它 Collections synchronizedList 但如果不进入非线程安
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 如何修复 JNLP 应用程序中的“缺少代码库、权限和应用程序名称清单属性”?

    随着最近的 Java 更新 许多人都遇到了缺少 Java Web Start 应用程序的问题Codebase Permissions and Application name体现属性 尽管有资源可以帮助您完成此任务 但我找不到任何资源综合的
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐

  • 基于.NET CORE 3.1的WEB API通过EF CORE连接MySQL

    基于 NET CORE 3 1的WEB API通过EF CORE连接MySQL 注 本文不采用CodeFirst 不使用迁移 1 准备好一个WEB API项目 可以看我之前的文章 2 准备好一个MySQL数据库并创建表 3 引用nuget包
  • 神经网络学习小记录44——训练资源汇总贴

    神经网络学习小记录44 训练资源汇总贴 前言 权值文件 1 迁移学习 传统神经网络 2 目标检测 a keras权重 b pytorch权重 c tensorflow2权重 3 实例分割 4 语义分割 旧版 5 语义分割 新版 a kera
  • nginx请求返回html文件,nginx返回json或者文本格式的方法

    用nginx怎么返回json格式或者文本格式的数据 其实很简单 如下代码 1 返回文本格式 location get text default type text html return 200 hello world 2 返回json格式
  • sublime配置go环境_Win10下sublime text3搭建go语言开发环境--工具篇

    进行 go 语言开发环境的搭建 最近进行了大量的搜索 因为在搭建的过程中遇到了挺多的问题 先介绍搭建的环境 系统 Win10 IDE sublime text3 相关插件 GoSublime 这篇文会介绍如下几个部分 1 下载Golang
  • 知道 Redis RDB 这些细节,可以少踩很多坑

    在使用 Redis 的过程中 你是否遇到过下面这些问题 开启 RDB 落盘 业务频繁出现请求超时 除了 save 和 bgsave 命令 还有哪些操作会触发 RDB 落盘 执行了 flushall 发现 flushall 之前写的数据又冒出
  • 根据传入的年份和月份获取该月属于本年的第几周和每周的开始和结束日期

    function getInfo year month var getInfo function year month var d new Date d setFullYear year month 1 1 var w1 d getDay
  • unity学习笔记-unity(2019)实现与as相互跳转

    Unity学习笔记 Unity 2019 嵌入安卓开发 实现相互跳转 思路 流程 先在unity中添加跳转到安卓的方法 AS配置unity的信息 2021 5 27更新一下 as添加跳转至unity的方法 as添加unity跳转到app的方
  • 8086CPU只有16位寄存器,却可以访问20位的物理地址

    一 背景介绍 Intel 8086是一个由Intel于1978年所设计的16位微处理器芯片 是x86架构的鼻祖 它是以8080和8085的设计为基础 拥有类似的寄存器组 但是数据总线扩充为16位 总线界面单元 Bus Interface U
  • javafx实现登录注册界面

    package sample import JavaBigJob BaseScene import javafx scene Parent import javafx scene layout Pane import javafx appl
  • 前端学习总结:5、Bootstrap

    前端学习总结 5 Bootstrap 文章目录 前端学习总结 5 Bootstrap 1 前言 2 资料 3 下载安装 Bootstrap 4 Bootstrap css 按钮 5 Bootstrap css 表格 6 Bootstrap
  • ZYNQ PL开发流程

    2 ZYNQ PL开发 开发流程 开发使用vivado 流程如下 1 新建工程 工程项目含义 这里简单介绍下各个工程类型的含义 RTL Project 是指按照正常设计流程所选择的类型 这也是常用的一种类型 RTL Project 下的 D
  • 《大话数据结构》-程杰 读书笔记

    认为程序设计的实质是对确定的问题选择一种好的结构 加上设计一种好的算法 可见 数据结构在程序设计当中占据了重要的地位 程序设计 数据结构 算法 要你相信自己一定可以学得会 学得好 既然无数人已经掌握了 你凭什么不行 于每个链表来说 它所占用
  • CentOS中安装docker-compose

    下载安装包 wget https github com docker compose releases download v2 2 3 docker compose linux x86 64 移动到 usr local bin 目录 mv
  • 【VUE3源码学习】nextTick 实现原理

    什么是nextTick 定义 在下次 DOM 更新循环结束之后执行延迟回调 在修改数据之后立即使用这个方法 获取更新后的 DOM 看完这个定义不免心生疑问 下次 DOM 更新循环结束之后是什么时候 执行延迟回调 更新后的 DOM 基于以上问
  • 使用 MMDETECTION 和 LABEL-STUDIO 进行半自动化目标检测标注

    标注数据是一个费时费力的任务 本文介绍了如何使用 MMDetection 中的 RTMDet 算法联合 Label Studio 软件进行半自动化标注 具体来说 使用 RTMDet 预测图片生成标注 然后使用 Label Studio 进行
  • Istio服务网格详解

    一 架构的发展历史 发展历史时间轴 1 单机小型机时代 第一个计算机网络诞生于1969年 也就是美军的阿帕网 阿帕网能够实现与其它计算机进行联机操作 但是早期仅仅是为了军事目的而服务 2000年初 中国的网民大约890万 很多人都不知道互联
  • Deepin设置接受从Windows的远程桌面连接

    信息化时代 网络越来越普及 电脑越来越多 经常会有使用远程桌面操作多台电脑 PC 服务器 虚拟机 云服务器等等 的情形 例如用远程桌面连接Windows服务器 台式机 Xshell连接Linux服务器 台式机 还有更多的工具 包括QQ远程协
  • 推多米诺

    LeetCode 838 推多米诺 一行中有 N 张多米诺骨牌 我们将每张多米诺骨牌垂直竖立 在开始时 我们同时把一些多米诺骨牌向左或向右推 每过一秒 倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌 同样地 倒向右边的多米诺骨牌也会推动竖
  • Java-对象转型(casting)

    对象转型 casting 一个基类的引用类型变量可以指向其子类的对象 一个基类的引用不可以访问其子类对象新增加的方法 属性 方法 可以使用 引用 变量instanceof类名 来判断该引用型变量所指向的对象是否属于该类或该类的子类 子类的对
  • 线程间通信方式

    参考视频 实现一个场景 三个线程分别交替打印A B C 打印100次 基于synchronized 锁的实现方式 public class test private static Integer num 0 public static vo