HashTable
单纯的使用一个synchronized进行加锁~,具体相当于针对整个 HashTable对象,但是坏处就是这样的话锁冲突的概率是非常高的
如果有多个线程,线程1操作的在第一个链表上,线程2操作的元素在别的链表上,这个时候不涉及到线程安全。
此时两个线程,修改不同的变量,实际上是没有线程安全的,但是HashTable直接一把锁,锁住了,线程1去操作的时候,线程2就会被阻塞等待,这样效率就会比较低。
此外,在扩容的时候,如果某个线程T正好触发了扩容,那么这个T就倒霉了,就要负责完成整个扩容过程~
ConcurrentHashMap
内部针对多线程做出了一定的优化,并不是针对整个对象加一把锁,而是分成了很多把锁~ 降低锁冲突的概率~
注意:java1.8之后才是这样分的,而java1.7里采用分段锁,好几个链表公用一把锁。
1.每个链表 / 红黑树 分配一把锁~
只有当两个线程恰好修改的是同一个链表/红黑树的时候才会涉及到锁冲突 ~