在并发量很小的情况下,也许大家平时用到的HashMap比较多。我们知道HashMap是线程不安全的,在多线程使用HashMap进行put操作会引起死循环,导致cpu利用率接近100%(已测试模拟100000个线程执行以uuid为key,put值操作,cpu达到百分之90多)。HashTable是使用synchronized保证线程安全的,但是线程竞争激烈的情况下效率低,如线程 1 使用 put 进行添加元素,线程 2 不但不能使用 put 方法添加元素,并且也不能使用 get 方法来获取元素。
ConcurrentHashMap解决高并发情况下线程安全和效率问题,是由Segment数组结构和HashEntry数组结构组成。Segment是一种可重入锁ReentrantLock,在ConcurrentHashMap里扮演锁的角色,HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组,Segment的结构和HashMap类似,是一种数组和链表结构,一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素,每个Segment守护一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。所图所示:[img]
[/img]
ConcurrentHashMap的get操作实现非常简单和高效。先经过一次再哈希,然后使用这个哈希值通过哈希运算定位到segment,再通过哈希算法定位到元素。get 操作的高效之处在于整个 get 过程不需要加锁,除非读到的值是空的才会加锁重读。put操作需要对共享变量进行写入操作,所以为了线程安全,在操作共享变量时必须得加锁。Put 方法首先定位到 Segment,然后在 Segment 里进行插入操作。插入操作需要经历两个步骤:第一步判断是否需要对 Segment 里的 HashEntry 数组进行扩容,第二步定位添加元素的位置然 后放在 HashEntry 数组里。size操作统计元素的大小,也就是统计所有Segment里元素的求和。统计的时候不是把所有Segment的put,remove,clean方法锁住,而是先尝试 2 次通过不锁住 Segment 的方式来统计各个Segment 大小,如 果统计的过程中,容器的 count 发生了变化,则再采用加锁的方式来统计所有 Segment 的大小。那么判断count是否发生变化判断的条件是:使用 modCount 变 量,在 put , remove 和 clean 方法里操作元素前都会将变量 modCount 进行加 1,那么在统计 size 前 后比较 modCount 是否发生变化,从而得知容器的大小是否发生变化。
ConcurrentLinkedQueue 是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对 节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部,当我们获取一个元素时,它 会返回队列头部的元素。类图结构如下:
由图可知:它由 head 节点和 tair 节点组成,每个节点(Node)由节点元素(item)
和指向下一个节点的引用(next)组成,节点与节点之间就是通过这个 next 关联起来,从而组成一张 链表结构的队列。默认情况下 head 节点存储的元素为空,tair 节点等于 head 节点。
这两个类是java.util.concurrent包下的类,以后工作中遇到要求多线程安全情况下可以尝试用这两个类。
参考资料:方腾飞java并发
- 大小: 298.3 KB
- 大小: 215.7 KB
分享到:
相关推荐
并发编程与高并发解决方案的学习笔记中,首先对并发与高并发进行了基本概念的介绍。并发指的是同时存在多个执行单元,但并不一定同时发生;而高并发是指系统能够同时处理很多的请求,这对于互联网分布式系统架构设计...
3. **并发工具类**:如`java.util.concurrent`包下的`Semaphore`(信号量)、`CyclicBarrier`(循环屏障)、`CountDownLatch`(倒计时锁)和`ExecutorService`等,它们提供了更高级别的线程管理和协作机制。...
本篇学习笔记将深入解析Java线程池的框架、结构、原理以及相关源码,帮助读者全面理解线程池的工作机制。 1. 线程池模块结构 线程池框架分为多层结构,其中包括核心实现类、辅助类和接口等组件。例如,`sun.nio.ch....
5. **并发集合**:`java.util.concurrent`包提供了线程安全的集合,如`ConcurrentHashMap`、`CopyOnWriteArrayList`和`BlockingQueue`等,它们在并发环境下有良好的性能表现。 6. **Future和ExecutorService**:`...
9. **并发容器**:`java.util.concurrent`包下提供了许多并发友好的容器,如`ConcurrentHashMap`、`CopyOnWriteArrayList`和`BlockingQueue`等,它们内部实现了线程安全的算法,避免了不必要的同步开销。 10. **...
4. **并发集合**:Java并发包(`java.util.concurrent`)提供了一系列线程安全的集合,如`ConcurrentHashMap`, `CopyOnWriteArrayList`, `BlockingQueue`等。笔记会解析它们的设计原理和使用技巧。 5. **线程池**:`...
Java.util.concurrent(JUC)是Java平台中的一个核心包,专门用于处理多线程并发问题。这个包包含了大量的工具类和接口,极大地简化了并发编程的复杂性,提高了程序的性能和可伸缩性。本测试源文件主要是针对JUC并发...
可重入锁是Java.util.concurrent.locks包下的ReentrantLock类,支持公平锁和非公平锁,具有比synchronized更细粒度的控制。它提供tryLock()方法,可以在无法获取锁时立即返回,而不是等待。 3. **ThreadLocal**: ...
使用java.util.concurrent类库构造安全的并发应用程序的基础。共享其实就是某一线程的数据改变对其它线程可见,否则就会出现脏数据。
另外,Java的并发包`java.util.concurrent`引入了显式锁(如`Lock`接口及其实现类),以及原语操作(如Atomic类),这些都为开发者提供了更细粒度的控制,可以在不使用synchronized的情况下实现线程安全。...
9. **Java常用库**:Java标准库(JDK)提供了大量工具类和API,如Util包下的各种工具类,以及并发库(java.util.concurrent)。熟悉并掌握这些库,可以极大地提高开发效率。 良葛格的Java学习笔记-V2,正是围绕以上...
java.util.concurrent java.util.concurrent java.util.locks java.util.atomic 进程/线程 并发/并行 线程 package com.ntuzy.juc_01 ; import java.util.concurrent.Callable ; import java.util.concurrent....
无锁编程,也称为Lock-Free Programming,是指在多线程环境下,通过避免使用传统的锁机制(如synchronized或java.util.concurrent.locks.Lock)来同步对共享数据的访问。这种技术依赖于原子操作(如CAS - Compare ...
### Java并发编程学习笔记知识点详解 #### 一、Java并发编程概述 Java并发编程是指在Java应用程序中同时执行多个操作的技术。它通过多线程、线程池等机制实现资源的有效利用,提高程序运行效率。Java并发编程的...
总的来说,这个压缩包中的源码和学习笔记是深入理解并熟练运用Java多线程、反射、泛型和正则表达式的宝贵资源。通过研究这些实例,开发者不仅可以巩固理论知识,还能提升实际编程技巧,从而在日常工作中编写出更加...
Java的并发库`java.util.concurrent`提供了高级并发工具,如ExecutorService、Future、CountDownLatch等,方便开发者高效地进行并发编程。 **并发编程代码示例** 压缩包中的`并发编程代码.zip`包含了实际的并发编程...
4. **并发集合**:Java并发包`java.util.concurrent`中提供了一系列并发安全的集合,如`ConcurrentHashMap`、`CopyOnWriteArrayList`和`BlockingQueue`等。这些集合在多线程环境下能保证数据一致性,避免数据竞争...
`synchronized`用于线程同步,`volatile`保证了内存可见性,而`java.util.concurrent`包则包含了许多高效并发工具,如`Semaphore`、`CountDownLatch`和`CyclicBarrier`等。 2. **线程池(ExecutorService)**: `...
`ExecutorService`和`ThreadPoolExecutor`是Java并发包`java.util.concurrent`中的关键组件,提供了线程池的创建和管理功能。 此外,Java还提供了多种同步机制来处理多线程间的交互,如`synchronized`关键字实现...