线程安全集合类
2023-12-14 20:02:46
JDK1.7 hashmap采用数组加链表头插的方式,在扩容时会出现循环死链问题,A->B->C扩容后C->B->A AB BA出现循环死链。
1. ConcurrentHashMap
HashTable
是线程安全的,但是HashTable只是单纯的方法层面上加上synchronized
。虽然安全,锁粒度太大了,所以性能不好。
口述:ConcurrentHashMap
并非锁住整个方法,像HashTable它直接在方法层面上加锁,粒度太大,ConcurrentHashMap它只锁了节点锁了一个链,而不是对整个table锁住,比如说put方法,它只是在要插入时才会加锁,吧插入的这个链表锁住,那table初始化啊、以及如果说当前位置没有元素时它会以CAS方式将节点插入,这些都没有锁,只有在插入时而且这个位置还有节点时才会加锁,粒度更小,并发性更高。而且get方法的话根本就没有加锁,也不是像HashTable那样吧方法上都加个synchronized,ConcurrentHashMap的get方法的话因为有volatile修饰table,也就保证了每次获取到的值都是最新的,也就不需要加锁。
2. LinkedBlockingQueue 阻塞队列
两把锁分别锁队头和队尾,其实就是保证消费者和生产者可以同步拿到对应的锁,你放你的我拿我的。多个消费者的话只有一个能拿到锁进行消费。
3. ConcurrentLinkedQueue
ConcurrentLinkedQueue 的设计与 LinkedBlockingQueue 非常像:
- 两把【锁】,同一时刻,可以允许两个线程同时(一个生产者与一个消费者)执行
- dummy 节点的引入让两把【锁】将来锁住的是不同对象,避免竞争
- 只是这【锁】使用了cas 来实现
例如之前讲的 Tomcat 的 Connector 结构时,Acceptor
作为生产者向 Poller 消费者传递事件信息时,正是采用了ConcurrentLinkedQueue 将 SocketChannel 给Poller
使用
4. CopyOnWriteArrayList
写入时拷贝
的思想,增删改
操作会将底层数组拷贝
一份,更改操作在新数组
上执行,这时不影响其它线程的并发读
,读-写并发,但可能读到的旧数据,有问题。
回顾:读写锁只是读读并发
文章来源:https://blog.csdn.net/qq_51240148/article/details/134993405
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!