线程安全的集合

一、常见集合中的线程安全集合

(一)Vector

Vector是常用的Collection集合中的线程安全的集合,其实现线程安全的原理是为其所有需要保证线程安全的方法都添加了synchronized关键字,锁住了整个对象。

使用锁的种类:互斥锁

源码展示:
Vector源码

Hashtable

HashtableVector类似,都是为每个方法添加了synchronized关键字,来实现的线程安全,锁住了整个对象。

使用锁的种类:互斥锁

源码展示:
Hashtable源码

二、使用Collections包装成线程安全

使用Collections包装成线程安全,本质上是将原本的集合在执行之前加上了synchronized(){}的对象锁,将对象先锁定再来运行。

使用锁的种类:互斥锁

  • 包装集合List
List<String> list = Collections.synchronizedList(new ArrayList<>());

源码展示:
Collections.synchronizedList源码展示

  • 包装集合Set
Set<String> set = Collections.synchronizedSet(new HashSet<>());
  • 包装集合Map
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());

源码展示:
Collections.synchronizedMap源码展示

三、concurrent包下的线程安全的集合

(一)CopyOnWriteArrayList

ArrayList的线程安全类

当多线程调用时,如果是读操作,和普通的ArrayList没有区别,如果是写操作,会先上锁,上锁后将数据复制一份,再将数据写入,避免数据覆盖而造成的数据问题。

使用锁种类:读写锁

读操作:

CopyOnWriteArrayList读操作源码展示
写操作:
CopyOnWriteArrayList写操作源码

(二)CopyOnWriteArraySet

HashSet的线程安全类。

CopyOnWriteArraySet底层使用的是CopyOnWriteArrayList

底层使用CopyOnWriteArrayList
add方法:

CopyOnWriteArraySet的add方法
判断元素是否存在,如果存在,返回false,如果不存在,添加元素。
addIfAbsent源码
addIfAbsent源码

### Java线程安全集合类及其实现方式 #### 1. 集合框架中的线程安全Java集合框架中并非所有的集合都默认提供线程安全保障。一些常见的集合类如`ArrayList`、`LinkedList`和`HashMap`等是非线程安全的[^2]。为了在多线程环境中使用这些集合而不引发数据一致性问题,开发者可以选择不同的策略来实现线程安全。 #### 2. 同步包装器 Java标准库提供了通过`Collections`工具类的方法将非线程安全集合转换为线程安全版本的功能。例如: - `Collections.synchronizedList(List<T> list)` 可以将一个普通的列表转为线程安全的列表。 - `Collections.synchronizedSet(Set<T> set)` 将集合同步化。 - `Collections.synchronizedMap(Map<K,V> map)` 对映射表进行同步处理。 这种方法虽然简单易用,但在高并发场景下性能可能较差,因为每次访问都需要加锁解锁操作[^3]。 ```java // 使用同步包装器创建线程安全的 List 和 Map 示例 List<String> syncList = Collections.synchronizedList(new ArrayList<>()); Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<>()); ``` #### 3. 并发包 (java.util.concurrent) 中的线程安全集合 除了上述基本的同步封装外,JDK还引入了一个专门用于解决高性能并发需求的包——`java.util.concurrent`。该包包含了多种针对特定用途优化过的线程安全集合类,比如: - **CopyOnWriteArrayList**: 当读取频率远高于修改频率时非常有效;它的工作原理是在写入时复制整个数组副本并更新新副本的内容后再替换旧副本[^4]。 ```java // 创建一个线程安全的可变长度数组 List<String> threadSafeList = new CopyOnWriteArrayList<>(); ``` - **ConcurrentHashMap**: 提供了高度优化的数据结构设计,允许更高的并发级别而无需完全锁定整个哈希表。其内部采用了分段锁技术(Segmented Locking),即把整个散列划分为若干个小部分分别上锁管理,从而减少争用情况下的等待时间[^1]。 ```java // 初始化 ConcurrentHashMap 实例 Map<Integer, String> concurrentMap = new ConcurrentHashMap<>(); // 插入键值对 concurrentMap.put(1, "Value"); // 获取指定 key 的 value 值 String result = concurrentMap.get(1); ``` - **BlockingQueue 接口及其具体实现**:适用于生产者消费者模式的应用场合。像 LinkedBlockingQueue 或 ArrayBlockingQueue 这样的队列实现了阻塞功能,在尝试向已满或者为空的队列执行插入/删除动作失败时会自动挂起当前线程直到条件满足为止。 ```java BlockingQueue<String> queue = new LinkedBlockingQueue<>(10); try { queue.put("Message"); // 如果队列满了,则此调用会被阻塞直至空间可用 } catch (InterruptedException e) {} ``` 综上所述,对于不同类型的业务逻辑以及具体的性能考量因素而言,选择合适的线程安全集合至关重要。如果只是偶尔发生少量竞争状况的话,那么简单的同步机制或许已经足够应付局面;然而一旦涉及到频繁存取且规模较大的共享资源情形之下,则应该优先考虑采用更先进的解决方案诸如那些来自 java.util.concurrent 包内的组件们。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值