当前位置: 首页 > news >正文

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 保证可见性,但不保证原子性(如递增操作需要 synchronizedAtomicInteger)。
  • 适用于简单的状态标识共享。

3. 使用线程安全的集合

Java 提供了多种线程安全的数据结构,比如 ConcurrentHashMapCopyOnWriteArrayList 等。

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 包提供了丰富的工具类来简化线程共享数据的操作,例如 CountDownLatchCyclicBarrierBlockingQueue

示例:使用 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:用于同步等待多个线程完成任务。

http://www.lryc.cn/news/492491.html

相关文章:

  • 【Leetcode Top 100】234. 回文链表
  • GitLab指定用户分配合并权限
  • 五,[GXYCTF2019]Ping Ping Ping1
  • 基于STM32的智能无人机自主飞行与目标识别系统设计
  • C 语言数组与函数:核心要点深度剖析与高效编程秘籍
  • 汽车轮毂结构分析有哪些?国产3D仿真分析实现静力学+模态分析
  • 解决jupyter notebook 新建或打开.ipynb 报500 : Internal Server Error(涉及jinja2兼容性问题)
  • 【若依ruoyi Vue前端线上个人服务器部署】以及常见报错问题解决
  • Python学习第十天--处理CSV文件和JSON数据
  • python基础(一)
  • go-carbon v2.5.0 发布,轻量级、语义化、对开发者友好的 golang 时间处理库
  • 守护进程
  • 学习日记_20241126_聚类方法(自组织映射Self-Organizing Maps, SOM)
  • 【接口自动化测试】一文从0到1详解接口测试协议!
  • 安全设备-日志审计-系统安装部署配置
  • 【ArcGIS Pro】实现一下完美的坐标点标注
  • Unity项目性能优化列表
  • 【系统架构设计师】高分论文:论软件架构的生命周期
  • 流量控制和拥塞控制的区别
  • CSS 背景、阴影和混合模式
  • 第49届ICPC亚洲区域赛,非凸科技再次支持上海赛站
  • 良好的并发编程习惯之封闭(Confinement)
  • docker镜像、容器、仓库介绍
  • 写个添加球队和展示球队的功能--laravel与inertia
  • 自制Windows系统(十)
  • World of Warcraft /script SetRaidTarget(“target“, n, ““) n=8,7,6,5,4,3,2,1,0
  • Rust中Tracing 应用指南
  • 海外媒体发稿:根据您的要求编写二十个文案标题方法-华媒舍
  • gitlab:使用脚本批量下载项目,实现全项目检索
  • macos 使用 nvm 管理 node 并自定义安装目录