Java多线程(十二)

目录

一、多线程环境使用哈希表

1.1 HashTable

1.2 ConcurrentHashTable

 二、ConcurrentHashMap和Hashtable、HashMap 的区别


一、多线程环境使用哈希表

HashMap 本身就是线程不安全的,所以在多线程的环境下可以使用:HashTable、 ConcurrentHashMap

1.1 HashTable

HashTable 只是简单的把关键方法加上了 synchronized 关键字

 

这就相当于对 HashTable 本身直接加锁

  • 如果多线程直接访问同一个HashTable 就会直接造成冲突
  • size属性也是通过synchronized来控制同步,也会降低效率
  • 一旦触发扩容,该线程就会完成整个扩容的效果,这个过程会涉及到大量的元素拷贝,效率很低

1.2 ConcurrentHashTable

ConcurrentHashTable 没有直接对整个方法进行加锁,而是进行 “锁桶” 操作,这样就会大大降低锁冲突的概率。

  • 读操作没有加锁(但是使用了 volatile 关键字保证从内存中读取结果)
  • 利用CAS的特性来控制size 属性,避免出现重量级锁的情况。
  • 优化了扩容方式:化整为零
  • 发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去.
  • 扩容期间, 新老数组同时存在.
  • 后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小部分元素.
  • 搬完最后一个元素再把老数组删掉.
  • 这个期间, 插入只往新数组加.
  • 这个期间, 查找需要同时查新数组和老数组

 二、ConcurrentHashMap和Hashtable、HashMap 的区别

  • HashMap: 线程不安全。key 允许为 null
  • Hashtable: 线程安全。使用 synchronized 锁 Hashtable 对象,效率较低。key 不允许为 null。
  • ConcurrentHashMap: 线程安全。使用 synchronized 锁每个链表头结点,锁冲突概率低,充分利用了CAS 机制。同时优化了扩容方式。key 不允许为 null。

猜你喜欢

转载自blog.csdn.net/x2656271356/article/details/132504130