0

0

Java 中实现组合数据的原子读取

花韻仙語

花韻仙語

发布时间:2025-08-13 21:44:39

|

400人浏览过

|

来源于php中文网

原创

java 中实现组合数据的原子读取

Java 中实现组合数据的原子读取

在并发编程中,保证多个相关数据的原子性读取至关重要,尤其是在需要维持数据一致性的场景下。例如,一个缓存系统同时维护了键列表、数据数组和大小信息,如果在读取这些信息时,缓存正在被更新,那么读取到的数据可能是不一致的。本文将探讨几种在 Java 中实现组合数据的原子读取的方法,并分析它们的优缺点。

1. 使用 synchronized 关键字

最直接的方法是使用 synchronized 关键字对读取和写入操作进行同步。

public class LocalCache {
    int size;
    List keys;
    float[] data;

    public synchronized void add(String oneKey, float[] oneData) {
        // 添加数据的逻辑
    }

    public synchronized void getData() {
        // 获取数据的逻辑
    }

    public synchronized List getKeys() {
        return keys;
    }

    public synchronized int getSize() {
        return size;
    }
}

// 使用示例
public void foo(LocalCache localCache) {
    synchronized(localCache) {
        localCache.getData();
        localCache.getKeys();
        localCache.getSize();
    }
}

这种方法的优点是简单易懂,能够保证在同一时刻只有一个线程可以访问 LocalCache 对象,从而避免了数据竞争。然而,它的缺点也很明显:当读取操作频繁发生时,写入操作会被阻塞,导致性能下降。

注意事项:

立即学习Java免费学习笔记(深入)”;

  • synchronized 关键字会锁定整个对象,因此需要仔细评估锁的粒度,避免过度锁定。

2. 使用 ReadWriteLock

如果读取操作远多于写入操作,可以考虑使用 ReadWriteLock。ReadWriteLock 允许多个线程同时读取数据,但只允许一个线程写入数据。

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class LocalCache {
    int size;
    List keys;
    float[] data;
    private final ReadWriteLock lock = new ReentrantReadWriteLock();

    public void add(String oneKey, float[] oneData) {
        lock.writeLock().lock();
        try {
            // 添加数据的逻辑
        } finally {
            lock.writeLock().unlock();
        }
    }

    public void getData() {
        lock.readLock().lock();
        try {
            // 获取数据的逻辑
        } finally {
            lock.readLock().unlock();
        }
    }

    public List getKeys() {
        lock.readLock().lock();
        try {
            return keys;
        } finally {
            lock.readLock().unlock();
        }
    }

    public int getSize() {
        lock.readLock().lock();
        try {
            return size;
        } finally {
            lock.readLock().unlock();
        }
    }
}

// 使用示例
public void foo(LocalCache localCache) {
    localCache.lock.readLock().lock();
    try {
        localCache.getData();
        localCache.getKeys();
        localCache.getSize();
    } finally {
        localCache.lock.readLock().unlock();
    }
}

这种方法的优点是可以提高读取操作的并发性,从而提高整体性能。然而,它的缺点是实现起来比 synchronized 关键字复杂,并且在写入操作频繁发生时,仍然可能导致性能瓶颈。

注意事项:

立即学习Java免费学习笔记(深入)”;

  • 务必在 try-finally 块中释放锁,以确保在发生异常时锁能够被正确释放。
  • ReadWriteLock 适合读多写少的场景。

3. 使用 ConcurrentLinkedQueue 和快照

如果对数据一致性的要求不是非常严格,可以考虑使用 ConcurrentLinkedQueue 和快照的方式。

Android配合WebService访问远程数据库 中文WORD版
Android配合WebService访问远程数据库 中文WORD版

采用HttpClient向服务器端action请求数据,当然调用服务器端方法获取数据并不止这一种。WebService也可以为我们提供所需数据,那么什么是webService呢?,它是一种基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合到一起。 实现Android与服务器端数据交互,我们在PC机器java客户端中,需要一些库,比如XFire,Axis2,CXF等等来支持访问WebService,但是这些库并不适合我们资源有限的android手机客户端,

下载
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.ArrayList;
import java.util.List;

class Data {
    String key;
    float[] oneData;

    public Data(String key, float[] oneData) {
        this.key = key;
        this.oneData = oneData;
    }
}

public class LocalCache {
    final Queue queue = new ConcurrentLinkedQueue<>();

    public void add(String key, float[] data) {
        queue.add(new Data(key, data));
    }

    public Queue getQueue() {
        return queue;
    }
}

// 使用示例
public void foo(LocalCache localCache) {
    List currentData = new ArrayList<>(localCache.getQueue());
    // 使用 currentData 进行后续操作
}

这种方法的优点是可以实现非常高的并发性,因为写入操作不需要加锁。然而,它的缺点是读取到的数据可能不是最新的,因为 currentData 只是队列的一个快照。

注意事项:

立即学习Java免费学习笔记(深入)”;

  • 这种方法只适用于对数据一致性要求不高的场景。
  • ConcurrentLinkedQueue 是无界队列,需要注意内存消耗。

4. 使用 ConcurrentHashMap

如果只需要一个支持并发访问的 Map,可以直接使用 ConcurrentHashMap。ConcurrentHashMap 内部使用了分段锁机制,可以实现非常高的并发性能。

import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

public class LocalCache {
    private final Map cache = new ConcurrentHashMap<>();

    public void add(String key, float[] data) {
        cache.put(key, data);
    }

    public float[] get(String key) {
        return cache.get(key);
    }
}

注意事项:

立即学习Java免费学习笔记(深入)”;

  • ConcurrentHashMap 适用于简单的键值对存储场景。
  • 需要根据实际情况选择合适的并发级别。

总结

选择哪种方法取决于具体的应用场景和对数据一致性的要求。

  • 如果对数据一致性要求非常高,且写入操作不频繁,可以使用 synchronized 关键字或 ReadWriteLock。
  • 如果对数据一致性要求不高,且需要非常高的并发性能,可以使用 ConcurrentLinkedQueue 和快照的方式。
  • 如果只需要一个支持并发访问的 Map,可以直接使用 ConcurrentHashMap。

在实际应用中,需要根据具体情况进行权衡,选择最适合的方法。同时,还需要注意代码的可读性和可维护性,避免过度优化。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

443

2023.08.02

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

579

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

102

2025.10.23

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

502

2023.08.10

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

75

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

60

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

40

2025.11.27

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

84

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 13.9万人学习

C# 教程
C# 教程

共94课时 | 7.8万人学习

SQL 教程
SQL 教程

共61课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号