线程安全的集合类
Vector,Stack,HashTable,是线程安全的(不建议⽤),其他的集合类不是线程安全的.
线程不安全的集合类
ArrayList
1.自行加锁,使用synchronized或者ReentrantLock
2.使用Collections.synchronizedList,这个类给list的关键方法加上了synchronized锁.
3.使用CopyOnWriteArrayList(写时复制的容器).
CopyOnWriteArrayList是:在添加新的元素时不直接添加在原容器中,而是先把原容器复制一份,再添加到复制出的容器中,添加完毕后将引用指向复制出的容器.
优点:在读多写少的情况下不需要加锁,性能较高.
缺点:占用内存较多(需要复制容器),写入后不能第一时间读到.
Queue
使用BlockingQueue(ArrayBlockingQueue,LinkedBlockingQueue,PriorityBlockingQueue),也可以使用TransferQueue,TransferQueue是只有一个元素的队列.
哈希表
1.使用HashTable,将关键方法加上了synchronized锁.
缺点:1).如果多线程访问同⼀个Hashtable就会直接造成锁冲突.
2).size也是通过加锁维护的,加锁也会导致维护变慢
3).⼀旦触发扩容,就由该线程完成整个扩容过程.这个过程会涉及到⼤量的元素拷⻉,效率会⾮常低.
为了解决上述缺点,就诞生了ConcurrentHashMap
2.ConcurrentHashMap
改进方法:
1.读操作不再加锁,只对写操作加锁,而且不再给方法加锁,而是将每个"桶"进行加锁(给链表头节点加锁),降低了锁冲突的概率.
2.充分利用CAS特性.⽐如size属性通过CAS来更新.避免出现重量级锁的情况.
3.更改扩容方式:
①发现需要扩容的线程,只负责创建一个新的哈希表并搬运少量数据.
②扩容期间,新老表都存在.插入只向新表中插入,查询在新旧两张表中进行.
③后续对这个哈希表操作的每个线程都要参与搬运少了数据.
④搬运完毕后,将老表删除.

被折叠的 条评论
为什么被折叠?



