Java基础夯实——2.9 多线程如何共享数据
在 Java 多线程编程中,共享数据通过以下几种方式实现:
1. 使用共享对象
多个线程可以通过引用同一个对象来实现数据共享。例如:
class SharedData {private int count;public synchronized void increment() {count++;}public synchronized int getCount() {return count;}
}public class Main {public static void main(String[] args) {SharedData sharedData = new SharedData();Thread t1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {sharedData.increment();}});Thread t2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {sharedData.increment();}});t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Final count: " + sharedData.getCount());}
}
解释:
- 使用
synchronized确保线程安全。 SharedData是共享的对象,多个线程共同操作它。
2. 使用 volatile 关键字
volatile 可用于标记变量,使得线程对其修改对其他线程立即可见。
class SharedData {private volatile boolean flag = false;public void toggleFlag() {flag = !flag;}public boolean isFlag() {return flag;}
}public class Main {public static void main(String[] args) {SharedData sharedData = new SharedData();Thread t1 = new Thread(() -> {while (!sharedData.isFlag()) {// 等待 flag 被修改}System.out.println("Flag is now true!");});Thread t2 = new Thread(() -> {try {Thread.sleep(1000); // 模拟延迟} catch (InterruptedException e) {e.printStackTrace();}sharedData.toggleFlag();});t1.start();t2.start();}
}
解释:
volatile保证可见性,但不保证原子性(如递增操作需要synchronized或AtomicInteger)。- 适用于简单的状态标识共享。
3. 使用线程安全的集合
Java 提供了多种线程安全的数据结构,比如 ConcurrentHashMap、CopyOnWriteArrayList 等。
import java.util.concurrent.ConcurrentHashMap;public class Main {public static void main(String[] args) {ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();Runnable task = () -> {for (int i = 0; i < 10; i++) {map.put(Thread.currentThread().getName() + i, i);}};Thread t1 = new Thread(task);Thread t2 = new Thread(task);t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(map);}
}
解释:
- 无需手动加锁,线程安全由集合实现。
4. 使用 ThreadLocal
ThreadLocal 为每个线程提供独立的变量副本,避免共享变量的竞争。
public class Main {private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);public static void main(String[] args) {Runnable task = () -> {threadLocal.set(threadLocal.get() + 1);System.out.println(Thread.currentThread().getName() + ": " + threadLocal.get());};Thread t1 = new Thread(task);Thread t2 = new Thread(task);t1.start();t2.start();}
}
解释:
- 适合线程独立的场景。
- 不适合真正需要共享数据的情况。
5. 使用并发工具类
Java 的 java.util.concurrent 包提供了丰富的工具类来简化线程共享数据的操作,例如 CountDownLatch、CyclicBarrier 和 BlockingQueue。
示例:使用 BlockingQueue
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class Main {public static void main(String[] args) {BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);Thread producer = new Thread(() -> {try {for (int i = 0; i < 10; i++) {queue.put(i);System.out.println("Produced: " + i);}} catch (InterruptedException e) {e.printStackTrace();}});Thread consumer = new Thread(() -> {try {for (int i = 0; i < 10; i++) {int value = queue.take();System.out.println("Consumed: " + value);}} catch (InterruptedException e) {e.printStackTrace();}});producer.start();consumer.start();}
}
解释:
- 适合生产者-消费者模式。
- 队列保证线程安全。
多线程如何共享数据?
1 使用共享变量
全局变量:直接声明为类的成员变量。
静态变量:用 static 关键字修饰的变量。
2 使用并发容器
ConcurrentHashMap:支持高效的并发读写操作。
ConcurrentLinkedQueue:适用于线程安全的队列操作。
3 使用线程安全的类
AtomicInteger:原子操作的整数类。
CountDownLatch:用于同步等待多个线程完成任务。
相关文章:
Java基础夯实——2.9 多线程如何共享数据
在 Java 多线程编程中,共享数据通过以下几种方式实现: 1. 使用共享对象 多个线程可以通过引用同一个对象来实现数据共享。例如: class SharedData {private int count;public synchronized void increment() {count;}public synchronized …...
【Leetcode Top 100】234. 回文链表
问题背景 给你一个单链表的头节点 h e a d head head,请你判断该链表是否为 回文链表(回文 序列是向前和向后读都相同的序列)。如果是,返回 t r u e true true;否则,返回 f a l s e false false。 数据…...
GitLab指定用户分配合并权限
进入项目 -》 Project Settings Repository -》展开 Protected branches -》 添加要保护的分支,设置角色 管理用户角色权限 查看到不同用户的角色,一般设置Developer只有Merger Request权限,Maintainer还有Merge审批权限 GitLab 中的权限…...
五,[GXYCTF2019]Ping Ping Ping1
进入靶场,有提示 我们在url试着输入本地IP,返回了ping命令 既然要在url处传参,那就用postman,再输入ip127.0.0.1 & ls,试着列出目录内容 ok,好像是个脏话,它过滤了空格 试着穿越又看到了脏话࿰…...
基于STM32的智能无人机自主飞行与目标识别系统设计
目录 引言系统需求分析 2.1 功能需求 2.2 硬件需求 2.3 软件需求系统设计 3.1 总体架构 3.2 各模块设计系统实现 4.1 硬件实现 4.2 软件实现系统调试与优化总结与展望 1. 引言 随着无人机技术的快速发展,无人机在军事侦察、环境监测、物流配送等领域的应用逐渐增多…...
C 语言数组与函数:核心要点深度剖析与高效编程秘籍
我的个人主页 我的专栏:C语言,希望能帮助到大家!!!点赞❤ 收藏❤ 目录 引言数组基础 2.1 数组的定义与初始化 2.2 一维数组的基本操作 2.3 二维数组及其应用 2.4 数组与指针的关系函数基础 3.1 函数的定义与调用 3.2…...
汽车轮毂结构分析有哪些?国产3D仿真分析实现静力学+模态分析
本文为CAD芯智库原创,未经允许请勿复制、转载! 之前分享了如何通过国产三维CAD软件如何实现「汽车/汽配行业产品设计」,兼容NX(UG)、Creo(Proe),轻松降低企业上下游图纸交互成本等。…...
解决jupyter notebook 新建或打开.ipynb 报500 : Internal Server Error(涉及jinja2兼容性问题)
报错: [E 10:09:52.362 NotebookApp] 500 GET /notebooks/Untitled16.ipynb?kernel_namepyt hon3 (::1) 93.000000ms refererhttp://localhost:8888/tree ...... 重点是: from .exporters import * File "C:\ProgramData\Anaconda3\lib\site-p…...
【若依ruoyi Vue前端线上个人服务器部署】以及常见报错问题解决
提示:【若依ruoyi Vue前端线上个人服务器部署】以及常见报错问题解决 文章目录 前言一、若依ruoyi Vue前端部署常见两种错误1、404问题2、找不到….模块 二、使用步骤(正式开始)1.修改vue.config.js中的publicPath属性。2.修改router/index.j…...
Python学习第十天--处理CSV文件和JSON数据
CSV:简化的电子表格,被保存为纯文本文件 JSON:是一种数据交换格式,易于人阅读和编写,同时也易于机器解析和生成,以JavaScript源代码的形式将信息保存在纯文本文件中 一、csv模块 CSV文件中的每行代表电…...
python基础(一)
python语言特点 解释型语言代码执行过程中通过解释器将代码转换为机器语言,并立即执行;编译型语言执行前需要经过编译整个代码文件为机器语言的可执行文件,然后执行能找出大部分错误错误处理解释型语言在运行时发现错误,编译型语…...
go-carbon v2.5.0 发布,轻量级、语义化、对开发者友好的 golang 时间处理库
carbon 是一个轻量级、语义化、对开发者友好的 Golang 时间处理库,提供了对时间穿越、时间差值、时间极值、时间判断、星座、星座、农历、儒略日 / 简化儒略日、波斯历 / 伊朗历的支持。 carbon 目前已捐赠给 dromara 开源组织,已被 awesome-go 收录&am…...
守护进程
目录 守护进程 前台进程 后台进程 session(进程会话) 前台任务和后台任务比较好 本质 绘画和终端都关掉了,那些任务仍然在 bash也退了,然后就托孤了 编辑 守护进程化---不想受到任何用户登陆和注销的影响编辑 如何…...
学习日记_20241126_聚类方法(自组织映射Self-Organizing Maps, SOM)
前言 提醒: 文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。 其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展…...
【接口自动化测试】一文从0到1详解接口测试协议!
接口自动化测试是软件开发过程中重要的环节之一。通过对接口进行测试,可以验证接口的功能和性能,确保系统正常运行。本文将从零开始详细介绍接口测试的协议和规范。 定义接口测试协议 接口测试协议是指用于描述接口测试的规范和约定。它包含了接口的请求…...
安全设备-日志审计-系统安装部署配置
3.1 系统安装部署概述 通过系统初始化安装部署,可实现对系统的基础管理工作。系统安装基本部署涉及功能有时间配置、 资产组、资产、用户组、用户、时间配置等) 3.2 系统安装部署配置举例 3.2.1 用户场景 本阶段进行系统安装,进行相关设…...
【ArcGIS Pro】实现一下完美的坐标点标注
在CAD里利用湘源可以很快点出一个完美的坐标点标注。 但是在ArcGIS Pro中要实现这个效果却并不容易。 虽然有点标题党,这里就尽量在ArcGIS Pro中实现一下。 01 标注实现方法 首先是准备工作,准备一个点要素图层,包含xy坐标字段。 在地图框…...
Unity项目性能优化列表
1、对象池 2、检查内存是否泄露。内存持续上升(闭包、委托造成泄露) 3、检查DrawCall数量,尽量减少SetPassCall 4、尽量多的利用四种合批 动态合批(Dynamic Batching)静态合批(Static Batching)GPUInstancingSRP Batcher 动态合批消耗内存把多个网格组合在一起合并…...
【系统架构设计师】高分论文:论软件架构的生命周期
更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 摘要正文摘要 2022 年5月,本人所在的某集团公司承接了财务共享服务平台综合管理系统的项目开发,该项目主要实现财务系统主流业务的集成共享。本人担任项目组成员中的系统架构设计师一职,全面负责项目的全生命周…...
流量控制和拥塞控制的区别
流量控制和拥塞控制是TCP协议中两个重要的机制,它们分别用于解决不同的问题。 流量控制 流量控制的目的是防止发送方发送数据过快,导致接收方来不及接收,从而避免分组丢失。流量控制是通过滑动窗口机制实现的,接收方在返回的ACK…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
