并发容器

ConcurrentHashMap

  • 设计原理

    • 分段锁(JDK 7) :将数据分成多个段(Segment),每个段独立加锁,不同段的操作可并行执行。
    • CAS + synchronized(JDK 8+) :取消分段锁,改用CAS(无锁算法)和细粒度synchronized锁桶(Node),进一步提升并发性能。
  • 核心特性

    • 线程安全:支持多线程并发读写,无需外部同步。
    • 高吞吐量:锁的粒度更细,减少线程竞争。
    • 弱一致性:迭代器遍历时可能不反映最新修改(但不抛出ConcurrentModificationException)。
  • 适用场景

    • 高并发读写(如缓存、计数器)。
    • 替代HashtableCollections.synchronizedMap
  • 对比传统同步容器

    特性 ConcurrentHashMap Hashtable/synchronizedMap
    锁粒度 细粒度(桶级别) 粗粒度(整个表)
    并发性能
    迭代器一致性 弱一致性 强一致性(可能抛出异常)

CopyOnWriteArrayList

  • 设计原理

    • 写时复制(Copy-On-Write) :每次修改(增、删、改)时,复制底层数组,在新副本上操作,完成后替换原数组。
    • 读操作无锁:直接访问原数组,无需同步。
    • 写操作加锁:保证同一时刻只有一个线程修改。
  • 核心特性

    • 线程安全:读操作完全无锁,写操作通过复制保证安全。
    • 数据一致性:迭代器遍历的是创建时的数组快照,不反映后续修改。
    • 内存开销:频繁修改会导致大量数组复制,占用内存。
  • 适用场景

    • 读多写极少(如监听器列表、配置白名单)。
    • 替代Collections.synchronizedList,在读远多于写时性能更优。
  • 对比传统同步容器

    特性 CopyOnWriteArrayList synchronizedList
    读性能 无锁,极高 需加锁,较低
    写性能 复制数组,较低 直接修改,较高
    内存占用 高(频繁写时)
    数据一致性 快照一致性 强一致性

并发容器适用场景

  • 高并发读写ConcurrentHashMap
  • 读多写极少CopyOnWriteArrayList
  • 写多读少 → 考虑ConcurrentLinkedQueue或阻塞队列(如LinkedBlockingQueue
  • 强一致性需求 → 慎用CopyOnWriteArrayList,优先使用锁同步的容器。

阻塞队列

Java阻塞队列

实现类 数据结构 特性
ArrayBlockingQueue 数组 有界队列,固定容量,公平性可选(基于ReentrantLock
LinkedBlockingQueue 链表 可选有界或无界(默认Integer.MAX_VALUE),吞吐量通常更高
PriorityBlockingQueue 堆(优先级队列) 无界队列,元素按优先级排序(需实现Comparable或提供Comparator
SynchronousQueue 无存储 直接传递队列,插入操作必须等待取出操作(无缓冲,适合线程间直接传递任务)
DelayQueue 堆(延迟队列) 无界队列,元素需实现Delayed接口,按到期时间排序(用于定时任务调度)
LinkedTransferQueue 链表 混合阻塞队列,支持transfer方法(生产者直接等待消费者取走元素)

阻塞队列的工作原理

  • 线程安全机制:内部通过ReentrantLockCondition实现线程同步
  • 锁分离:插入和取出操作使用不同的锁(如LinkedBlockingQueueputLocktakeLock),减少竞争。
  • 条件变量:队列空或满时,通过Conditionawait()signal()实现阻塞与唤醒。

阻塞队列的典型使用场景

  • 生产者-消费者模式:适合任务量不可控但需快速响应的场景(如日志处理)。
  • 线程池任务调度:Java线程池(如ThreadPoolExecutor)默认使用LinkedBlockingQueue存储待执行任务。
  • 流量削峰与系统解耦:在高并发场景下,用队列缓冲瞬时流量,保护下游系统。

阻塞队列的选择与调优

  • 队列容量

    • 有界队列(如ArrayBlockingQueue):避免内存溢出,但需合理设置容量,防止任务被拒绝。
    • 无界队列(如LinkedBlockingQueue):可能因任务堆积导致内存耗尽,需谨慎使用。
  • 公平性

    • 公平锁(fairness=true)减少线程饥饿,但降低吞吐量;非公平锁(默认)反之。

      ArrayBlockingQueue<Integer> fairQueue = new ArrayBlockingQueue<>(100, true);
  • 特殊需求

    • 优先级调度PriorityBlockingQueue
    • 延迟任务DelayQueue
    • 直接传递任务SynchronousQueue

阻塞队列的常见问题

  • 死锁风险

    • 场景:多个线程互相等待对方释放资源。
    • 解决:使用超时方法(如poll(timeout)),避免无限阻塞。
  • 资源耗尽

    • 场景:无界队列导致内存溢出。
    • 解决:改用有界队列,配合拒绝策略(如线程池的RejectedExecutionHandler)。
  • 性能瓶颈

    • 场景:队列成为系统吞吐量的瓶颈。
    • 解决:优化队列类型(如LinkedTransferQueue提升吞吐量),或增加消费者线程。

同步工具类

CountDownLatch

  • 核心功能

    • 一次性屏障:允许一个或多个线程等待其他线程完成操作后再继续执行。
    • 计数器递减:初始化时设定计数值(count),线程调用countDown()减少计数,计数归零时唤醒等待线程。
  • 主要方法

    • CountDownLatch(int count) :构造函数,指定初始计数。
    • await() :阻塞当前线程,直到计数归零。
    • countDown() :减少计数值,计数为0时唤醒所有等待线程。
  • 使用场景:主线程等待所有子任务完成;多线程等待同一事件触发(如模拟并发测试)

Semaphore

  • 核心功能

    • 控制资源访问的并发数:通过许可证(permits)限制同时访问某资源的线程数量。
    • 可公平/非公平模式:默认非公平,按请求顺序或竞争获取许可证。
  • 主要方法

    • Semaphore(int permits) :构造函数,指定许可证数量。
    • acquire() :获取许可证(若无可用则阻塞)。
    • release() :释放许可证。
    • tryAcquire() :非阻塞尝试获取许可证。
  • 使用场景:限流(如数据库连接池);实现互斥锁(许可证为1的信号量)

CyclicBarrier

  • 核心功能

    • 可重置的屏障:让一组线程相互等待,直到所有线程到达屏障点后同时继续执行。
    • 支持回调:所有线程到达屏障后,可触发一个Runnable任务。
  • 主要方法

    • CyclicBarrier(int parties) :构造函数,指定参与的线程数。
    • CyclicBarrier(int parties, Runnable barrierAction) :指定到达屏障后的回调任务。
    • await() :线程到达屏障点并等待其他线程。
  • 使用场景:分阶段并行计算;多线程数据合并(如分布式计算)

同步工具对比与选型

工具 核心机制 重用性 典型场景
CountDownLatch 等待其他线程完成 一次性 主线程等待子任务、并发触发
Semaphore 控制资源访问并发数 可重用 限流、资源池(如数据库连接)
CyclicBarrier 多线程相互等待至屏障点 可重用 分阶段任务、数据合并Java并发并发编程实战-并发容器和同步工具类

Java并发并发编程实战-并发容器和同步工具类的更多相关文章

  1. java 利用同步工具类控制线程

    前言 参考来源:<java并发编程实战> 同步工具类:根据工具类的自身状态来协调线程的控制流.通过同步工具类,来协调线程之间的行为. 可见性:在多线程环境下,当某个属性被其他线程修改后,其 ...

  2. Java核心知识点学习----线程同步工具类,CyclicBarrier学习

    线程同步工具类,CyclicBarrier日常开发较少涉及,这里只举一个例子,以做备注.N个人一块出去玩,相约去两个地方,CyclicBarrier的主要作用是等待所有人都汇合了,才往下一站出发. 1 ...

  3. 《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&并发容器类&同步工具类,消费者模式

    上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Has ...

  4. Java并发(基础知识)——显示锁和同步工具类

    显示锁                                                                                     Lock接口是Java ...

  5. 并发是个什么鬼之同步工具类CountDownLatch

    扯淡 写这篇文章,我先酝酿一下,实不相瞒,脱离底层太久了,更确切的情况是,真没曾认真研究过.就目前来说,很多框架包括工具类已经把实现封装的很深,你只需轻轻的调用一下API,便不费半点力气.以至于大家会 ...

  6. java.util.concurrent中的几种同步工具类

    java.util.concurrent并发包中提供了一系列的的同步工具类,这些基础类不管是否能在项目中使用到,了解一下使用方法和原理对java程序员来说都是有必要的.博主在看<java并发编程 ...

  7. Java并发之同步工具类

    1. CountDownlatch(计数器) 描述: 一个同步工具类,允许一个或多个线程等待其它线程完成操作 类图 通过指定的count值进行初始化,调用await方法的线程将被阻塞,直到count值 ...

  8. Java中创建操作文件和文件夹的工具类

    Java中创建操作文件和文件夹的工具类 FileUtils.java import java.io.BufferedInputStream; import java.io.BufferedOutput ...

  9. 获取Spring容器Bean对象工具类

    在开发中,总是能碰到用注解注入不了Spring容器里面bean对象的问题.为了解决这个问题,我们需要一个工具类来直接获取Spring容器中的bean.因此就写了这个工具类,在此记录一下,方便后续查阅. ...

  10. Java多线程同步工具类之CountDownLatch

    在过去我们实现多线程同步的代码中,往往使用join().wait().notiyAll()等线程间通信的方式,随着JUC包的不断的完善,java为我们提供了丰富同步工具类,官方也鼓励我们使用工具类来实 ...

随机推荐

  1. 部署博客(docker)

    参考:链接 准备一台新的服务器 安全组:8080.80.3306等端口放通 安装docker 参考: 链接 获取最新镜像 docker pull b3log/solo 报错,可能是docker未启动, ...

  2. oracle 根据节点id递归查询全部的父节点(转载)

    本文转载自   https://blog.csdn.net/BondChenJ/article/details/78581625 1.适用状况:blog 适用树状结构数据,例如包含id,parent_ ...

  3. 初识VPC网络的能力

    本文分享自天翼云开发者社区<初识VPC网络的能力>,作者:布小匠 VPC网络的来源 在云计算早期是没有VPC的概念的,有的是虚拟网络和虚拟路由器的功能.虚拟网络的作用是为用户提供一个虚拟的 ...

  4. dotnet CLI推送Nuget

    前提: 准备好要发布的包 选择一个打包工具,可以是dotnet CLI.nuget.exe CLI.MSBuild 准备好Nuget官方API Key 自述文件   先必须添加Readme.md到项目 ...

  5. PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?

    在之前的三篇文章中,笔者介绍了有关DeepSeek的基础操作,满足了不同类型的用户需求. 想利用大模型构建属于自己的智能知识库,无论你是想私有化部署,还是直接使用API调用,都可以在这三篇文章中找到答 ...

  6. 多项式算法再探:FMT 和 FWT

    我们知道,FFT 和 NTT 可以用来解决下面这种问题: \[c_k=\sum_{i+j=k}a_ib_j \] 不过,这并不是卷积的全部形态,比如下面这种: \[c_k=\sum_{i*j=k}a_ ...

  7. 功率MOS管的参数说明

    图解功率MOS管的每一个参数!   最大额定参数 最大额定参数,所有数值取得条件(Ta=25℃) VDSS 最大漏-源电压 在栅源短接,漏-源额定电压(VDSS)是指漏-源未发生雪崩击穿前所能施加的最 ...

  8. 5090D-deepseek-Anythingllm-Ollama运行测试

    ollama ollama配置环境变量 ollama地址与镜像 C:\Users\DK>curl http://10.208.10.240:11434 Ollama is running C:\ ...

  9. docker - [05] 部署Nginx

    题记部分 一.查找镜像 docker search nginx 二.拉取镜像 docker pull nginx 三.启动镜像 Nginx默认端口号为80,可以在启动时指定Nginx使用的端口号(例如 ...

  10. Zookeeper - 本地模式部署

    本地模式部署 zoo.cfg 参数解析 本地模式部署 1.上传zookeeper的安装包并解压 tar -zxvf zookeeper-x.x.x.tar.gz -c /xxx/xxx/ 2.将 zo ...