HashMap在多线程环境下是不安全的,只能在单线程下使用.
多线程下安全的只有:
- HashTable
- ConcurrentHashMap
HashTable
HashTable在多线程环境下安全的原因是,给其的get与put方法都使用synchronized修饰了,被锁的对象是整个HashTable,只要有线程对此HashTable操作就上锁,其他尝试获取的线程会进入阻塞模式.
HashTable的扩容方式为:
创建一个更大容量的HashTable并由触发扩容的线程单独进行拷贝旧HashTbale的数据,效率较低.
ConcurrentHashMap
ConcurrentHashMap中的读操作并没有进行上锁,而只是用了volatile保证了其内存可见性.
对写操作进行了上锁,但锁的对象并不是整个ConcurrentHashMap,而是一个单独的哈希桶.
只有多个线程向同一个哈希桶写入数据时才会导致阻塞,极大的提升了效率.
CouncurrentHashMap的扩容:
创建一个新的CouncurrentHashMap,同时只拷贝几个元素过去.
后续每次调用此CouncurrentHashMap的线程在进行操作后,再从旧的CouncurrentHashMap中拷贝几个元素过去.
直到完全拷贝成功,旧的CouncurrentHashMap才会被销毁
新添加的元素会被直接添加到新的CouncurrentHashMap当中