0
点赞
收藏
分享

微信扫一扫

python数据处理库——Pandas

ixiaoyang8 2024-08-23 阅读 30

目录

前言

顺序表

队列

哈希表

1、Hashtable

2、ConcurrentHashMap(重点)


前言

本文章主要介绍在多线程环境下如何线程安全的使用一些常用的集合类(顺序表和哈希表)。


顺序表

1、自己使用同步锁机制(synchornized和ReentrantLock)保证线程安全

2、Collections.synchronizedList()

3、写时拷贝

Java中提供了CopyOnWrit这个容器来解决线程安全问题。

它的解决思路是:

优点:

缺点:


队列

关于队列的线程安全,自然使用到的是阻塞队列:

1. ArrayBlockingQueue:   基于数组实现的阻塞队列

2. LinkedBlockingQueue: 基于链表实现的阻塞队列

3. PriorityBlockingQueue: 基于堆实现的带优先级的阻塞队列

4. TransferQueue:             最多只包含⼀个元素的阻塞队列


哈希表

HashMap本身是线程不安全的,在多线程环境下可以使用Hashtable/ConcurrentHashMap

1、Hashtable

Hashtable这个类只是对HashMap进行简单的加锁,也就是在关键方法上增加了synchronized关键字:

这就导致只要多个线程同时调用put或者get方法,即使他们想要访问的不是同一组数据,照样会进入阻塞状态,也就是所冲突,极大的影响了运行效率。

另外,如何在某一个线程使用put操作时,如果需要扩容,那么就会由当前线程进行扩容,如果涉及大量的元素拷贝,那么多线程的运行效率又会大幅降低。

总的来讲,HashTable相当于对整个哈希桶上了锁:

2、ConcurrentHashMap[推荐使用]

为了降低锁冲突概率,ConcurrentHashMap做出了以下优化:

  • 读操作:没有加锁,但是加了volatile保证内存可见。
  • 写操作:对每一个链表都进行了加锁(synchronized实现),如果写入数组中不同的下标,那么就不会发生所冲突,如图:
  • CAS的使用:在锁竞争并不激烈的情况下,采用CAS来更新size(键值对 增加/减少),这种方式不用加锁,更轻量,提高运行效率(jdk8引入)。
     
  • 分散计数器槽:在锁竞争激烈时,使用CAS就可能出现忙等的情况,使用CAS修改size就不太好了。为了避免多个线程同时修改同一个数据(size),ConcurrentHashMap引入了分散计数器槽(Counter Cells),它的原理如下:
  • 扩容方式:与HashTable让发现需要扩容的线程去完成整个扩容任务不同,Concurrent把扩容任务分散给了多个线程去完成,即“化整为零”。
    大致步骤如下:​​​​

这种扩容方式大大提高了并发性能(逐步迁移,降低阻塞概率)以及系统稳定性(扩容时,单个线程锁占用时间不会激增)。


举报

相关推荐

0 条评论