我是靠谱客的博主 勤恳水杯,最近开发中收集的这篇文章主要介绍集合的线程安全性、为什么HashMap,ArrayList不是线程安全的?体现在哪?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 一.集合的线程安全性
    • 二.线程不安全集合举例分析.
      • 1.ArrayList.
      • 2.HashMap.
    • 三.concurrentHashMap相对于hashMap的优化(jdk1.8)

一.集合的线程安全性

      我们通常所讲的某个集合是线程安全的,指的是单个操作是线程安全的,也就是需要具体到某个变量或方法的,如果是多个连续的操作,并不能保证这些连续的操作是线程安全的.

      比如我们通常说hashTable是线程安全的.那假如现在有一个hashTable,里面有一个键值对key:test
现在有两个线程a和b均需要给这个key的值末尾添加字符a,预期的结果是这样的key:testaa
那假设这两个线程的执行顺序是这样的:
   1.线程a读出key的值:test
   2.线程b读出key的值:test
   3.线程a在末尾添加字符a,然后进行写入
   4.线程b在末尾添加字符a,然后进行写入
此时的结果是key:testa,并不是我们预期的结果,那hashtable算不算线程安全的呢?

      还是算的,因为线程安全是指 变量或方法在多线程环境下能够被安全有效的访问,针对于hashTable的单个方法来说,确实是进行了正确的处理,所以是线程安全的.

二.线程不安全集合举例分析.

1.ArrayList.

      比如一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。

      在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;
      而如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。
      那好,我们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了.

2.HashMap.

以jdk1.8为例分析.
      在jdk1.8中,hashMap将头插法改成了尾插法,解决了死循环的问题,但是还会有数据丢失的问题,这个场景很多博客都说的不对,这里着重说明一下.

      假设有两个线程a和b,同时往hashMap中put键值对,这两个键值对的key不相等,但是hash值是一样的.

      那在hashMap中,因为没有加锁,是并行执行的,所以当两个线程都同时执行到以下代码时,tab[i]最终只会指向其中一个,另一个数据会被覆盖,map中只会有一条数据,也就造成数据丢失的情况.
在这里插入图片描述

三.concurrentHashMap相对于hashMap的优化(jdk1.8)

      而在concurrentHashMap中,采用了CAS+synchronized的方式(jdk1.8)去处理多线程,就是一个Node数组+链表/红黑树的结构,锁的是Node数组中的某个Node节点.
在这里插入图片描述

当某个Hash值对应Node数组中的位置为空时,采用CAS进行赋值.
在这里插入图片描述
当某个Hash值对应的数组位置不为空时,会锁住该数组中Node节点,并以该Node节点为链表的首节点,依次向后添加新节点.
在这里插入图片描述
      所以,当出现上面那种情况时---->有两个线程a和b,同时往concurrentHashMap中put键值对,并且这两个键值对的key不相等,但是hash值是一样的.

      两个线程会先同时进行CAS操作,给Node数组中对应的位置赋值,此时一定一个执行成功,往Node数组中成功添加a节点,另一个执行失败,那么执行失败的这个线程会使用synchronized锁住a节点,将这个a节点作为链表的首节点,然后在后面添加新节点,此时map中两个键值对都可以添加成功,就是线程安全的了.

======================================================================================================
如果你需要阅读专业书籍来提升自己,可以关注博主的公众号,回复 图书即可获得几百本程序员必读书籍.

包含以下所有分类中的各种经典书籍.
在这里插入图片描述
006QslZHly8h66jmes3esj30go0gowg9.jpg

今天的分享就到这里了,有问题可以在评论区留言,均会及时回复呀.
我是bling,未来不会太差,只要我们不要太懒就行, 咱们下期见.
在这里插入图片描述

最后

以上就是勤恳水杯为你收集整理的集合的线程安全性、为什么HashMap,ArrayList不是线程安全的?体现在哪?的全部内容,希望文章能够帮你解决集合的线程安全性、为什么HashMap,ArrayList不是线程安全的?体现在哪?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部