java中的多线程通信问题介绍

news2024/10/26 4:19:58

        在多线程编程中,通信是线程间协调和同步的重要手段。由于线程是独立执行的,它们需要一种机制来交换信息和协调它们的行为。Java 提供了多种方式来实现线程间的通信,包括共享内存、消息传递、条件变量和共享对象等。


        1. 共享内存
在 Java 中,最简单的线程通信方式是通过共享内存变量。这种方法通常使用 `synchronized` 关键字或 `ReentrantLock` 类来保护共享资源,确保线程安全。
        应用场景
- 当多个线程需要访问和修改同一个共享资源时。
        例子
        

public class SharedMemoryExample {
    private int count = 0;
    public synchronized void increment() {
        count++;
    }
    public static void main(String[] args) {
        SharedMemoryExample example = new SharedMemoryExample();
        Thread t1 = new Thread(example::increment);
        Thread t2 = new Thread(example::increment);
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Count is: " + example.count);
    }
}


        
         2. 消息传递
        消息传递是一种更高级的线程通信方式,它允许线程通过发送和接收消息来交换信息。Java 中的 `wait()`、`notify()` 和 `notifyAll()` 方法可以用于实现这种通信机制。
        应用场景
- 当线程需要等待某些事件或条件时。
        例子


public class MessagePassingExample {
    public static Object lock = new Object();
    public static boolean flag = false;
    public void waitForMessage() {
        synchronized (lock) {
            while (!flag) {
                try {
                    lock.wait(); // 线程等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public void sendMessage() {
        synchronized (lock) {
            flag = true;
            lock.notify(); // 通知等待的线程
        }
    }
    public static void main(String[] args) {
        MessagePassingExample example = new MessagePassingExample();
        Thread t1 = new Thread(example::waitForMessage);
        Thread t2 = new Thread(example::sendMessage);
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


        
        3. 条件变量
        条件变量允许线程在某些条件下等待或被通知。它们通常与 `wait()`、`notify()` 和 `notifyAll()` 方法一起使用。
        应用场景
- 当线程需要根据某些条件来执行操作时。
        例子


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionExample {
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private boolean conditionMet = false;
    public void waitForCondition() {
        lock.lock();
        try {
            while (!conditionMet) {
                try {
                    condition.await(); // 线程等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } finally {
            lock.unlock();
        }
    }
    public void setCondition() {
        lock.lock();
        try {
            conditionMet = true;
            condition.signal(); // 通知等待的线程
        } finally {
            lock.unlock();
        }
    }
    public static void main(String[] args) {
        ConditionExample example = new ConditionExample();
        Thread t1 = new Thread(example::waitForCondition);
        Thread t2 = new Thread(example::setCondition);
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


         4. 共享对象
        共享对象是一种线程通信方式,其中线程通过访问和修改共享对象的状态来交换信息。这种方法通常使用 `volatile` 关键字来确保变量的可见性。
        应用场景
- 当线程需要访问和修改同一个共享对象时。
        例子


public class SharedObjectExample {
    private volatile boolean flag = false;
    public void waitForObject() {
        while (!flag) {
            Thread.yield(); // 线程让步
        }
    }
    public void setObject() {
        flag = true;
    }
    public static void main(String[] args) {
        SharedObjectExample example = new SharedObjectExample();
        Thread t1 = new Thread(example::waitForObject);
        Thread t2 = new Thread(example::setObject);
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


        
        总结
        Java 多线程中的通信问题涉及到线程间的信息交换和行为协调。共享内存、消息传递、条件变量和共享对象是实现线程通信的常见方式。共享内存通过 `synchronized` 关键字或 `ReentrantLock` 类来保护共享资源,确保线程安全。消息传递使用 `wait()`、`notify()` 和 `notifyAll()` 方法来实现线程间的等待和通知。条件变量允许线程在某些条件下等待或被通知。共享对象通过访问和修改共享对象的状态来交换信息,通常使用 `volatile` 关键字来确保变量的可见性。
        在实际应用中,选择合适的线程通信方式取决于具体的需求和场景。例如,如果你需要一个简单的同步机制,共享内存可能是最直接的选择。如果你需要线程间的协调,消息传递或条件变量可能更加适合。而当你需要线程访问和修改同一个对象时,共享对象可能更加适合。
        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1497324.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue2的element UI 表格单选

代码 this.$refs.multipleTable.toggleRowSelection(selection.shift(), false);multipleTable 是定义的表格的ref

Kubernetes(K8S之存储)

configmap configMap描述信息 configMap功能在Kubernetes1.2版本中引入,许多应用程序会从配置文件,命令行参数或环境变量中读取配置信息。ConfigMap API给我们提供了向容器中注入配置信息的机制。ConfigMap可以被用来保存单个属性。 也可以用来保存整…

二叉树前序遍历函数 代码图解(先序遍历 深度优先遍历)

void PreOrder(BiTree p)//只是遍历 即只是读,不会改变树根 {//这个p的类型是 树的结构体 不是之前的p指针if(p!NULL){printf("%c", p->c);PreOrder(p->lchild);//函数嵌套 打印左子树PreOrder(p->rchild);//函数嵌套 打印右子树} } 同理可证 中…

如何在Win系统本地部署Jupyter Notbook交互笔记并结合内网穿透实现公网远程使用

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 在数据分析工作中,使用最多的无疑就是各种函数、图表、…

windows部署ruoyi-vue-pro

前提 安装java 安装maven 安装redis mysql 源代码下载 后端 ruoyi-vue-pro 前端 yudao-ui-admin-vue3 后端项目 配置maven 导入数据 CREATE DATABASE ruoyi_vue_pro;修改mysql连接配置 修改redis 打包项目 mvn clean install package -Dmaven.test.skiptrue启动YudaoSe…

Linux CentOS系统安装Spug并结合内网穿透实现远程访问本地运维平台

目录 前言 1. Docker安装Spug 2 . 本地访问测试 3. Linux 安装cpolar 4. 配置Spug公网访问地址 5. 公网远程访问Spug管理界面 6. 固定Spug公网地址 结语 作者简介: 懒大王敲代码,计算机专业应届生 今天给大家聊聊Linux CentOS系统安装Spug并结合…

19-Java中介者模式 ( Mediator Pattern )

Java中介者模式 摘要实现范例 中介者模式(Mediator Pattern)提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护中介者模式是用来降低多个对象和类之间的通信复杂性中介者模式属于行为型模式…

快递包装展|2024上海国际电商物流包装产业展览会

2024中国(上海)国际电商物流包装产业展览会 2024 China (Shanghai) international e-commerce logistics packaging industry exhibition 时 间:2024年7月24日 —7月26日 地 点:国家会展中心(上海市青浦区崧泽大道333号&#xff…

Vue3.0 vue.js.devtools无法显示Pinia调试工具

之前的配置方式: app.use(createPinia()) app.mount(#app) 更新配置方式: app.use(createPinia()).mount("#app") 设置之后即可显示调试工具

Python学习笔记-Flask实现简单的抽奖程序

1.导入flask包和randint包 from flask import Flask,render_template from random import randint 2.初始化 Flask 应用: app Flask(__name__) 3. 定义英雄列表 hero [黑暗之女,狂战士,正义巨像,卡牌大师,德邦总管,无畏战车,诡术妖姬,猩红收割者,远古恐惧,正义天使,无极剑…

kasan排查kernel内存越界示例(linux5.18.11)

参考资料: 1,内核源码目录中的Documentation\dev-tools\kasan.rst 2,KASAN - Kernel Address Sanitizer | Naveen Naidu (naveenaidu.dev) 一、kasan实现原理 KASAN(Kernel Address SANitizer)是一个动态内存非法访…

Leetcoder Day39| 动态规划part06 完全背包问题

完全背包理论 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。 示例: 背包最大…

CentOS下安装RabbitMQ

准备工作,更新yum源 正式环境慎用 yum update -y # 进入目录 cd /etc/yum.repos.d/ # 创建目录 mkdir backup # 默认源配备份 mv C* backup/ # 下载阿里云yum源 wget -O /etc/yum.repos.d/CenOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo # 清除旧…

【BUG修复日志】Anaconda + VSCode 编码错误

【BUG修复日志】Anaconda VSCode 编码错误 平台: Windows11家庭版 (v22621.3155) 软件: Visual Studio Code (v1.87.0) 插件: Python (v2024.2.1) 版本: Conda (v24.1.2)问题描述 VSCode 在安装 Python 插件的情况下自动提示配置 Conda 环境,但是在自动配置完成后…

P9889 [ICPC2018 Qingdao R] Plants vs. Zombies 题解 二分+贪心

[ICPC2018 Qingdao R] Plants vs. Zombies 传送门 题面翻译 给定 n n n 个植物和 m m m 的步数限制,每个植物在位置 1 … n 1\dots n 1…n 上。你初始时在位置 0 0 0,每次可以移动到相邻的位置上。 每次设你走完一步后到达的位置是 i i i&#…

LeetCode每日一题之 快乐数

目录 题目介绍: 算法原理: 鸽巢原理: 如何找到环里元素: 代码实现: 题目介绍: 题目链接:. - 力扣(LeetCode) 算法原理: 我先简单举两个例子&#xff…

最新的前端开发技术(2024年)

关于作者: 还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas&#xff0…

如何将虚拟机设置成固定IP

问题描述: 在VMware虚拟机上部署的项目ip地址和数据库ip地址发生变动,导致mysql,nginx,redis等无法访问,要改配置又特别麻烦,而且下次可能还会变动。 解决方法: 将虚拟机ip地址配置成固定ip 关闭虚拟机,找…

ai数字人虚拟直播:AI大模型带给你不一样的体验

AI数字人虚拟直播,这一新兴的科技形式,正逐渐融入人们的生活之中。通过AI大模型的技术支持,数字人可以实现高度仿真的互动体验,让观众感受到前所未有的沉浸式乐趣。 数字人虚拟直播的魅力在于其超越了传统直播形式的局限性&#…

R语言lavaan结构方程模型在复杂网络分析中的科研技术新趋势

此外,我们还将深入探讨R语言的基础知识、结构方程模型的基本原理、lavaan程序包的使用方法等内容。无论是潜变量分析、复合变量分析,还是非线性/非正态/缺失数据处理、分类变量分析、分组数据处理等复杂问题,我们都将一一为您解析。 希望通过…