集合类线程不安全

主要在add,remove时报: java.util.ConcurrentModificationException(并发修改异常)

为什么会出现这个异常:

比如当A线程在添加数据的时候,B线程突然进来,把A线程要添加数据的位置,增加了自己的数据,紧接着A线程重新执行,再次修改了刚刚的数据,把B线程的数据,修改成自己的数据,这个会导致数组内有空值或者抛出异常

解决办法:

  • 使用Vector
  • 使用Collections
  • 使用CopyandWriteArraryList();

                     

       在写时加锁,先将整个数据对象复制一份,并将长度增加1,然后把数据添加到数组的最后位置,返回true

补充:synchronized里面的lock

                

为什么这里使用这个对象作为锁(对象锁):

首先就是CopyandWriteArraryList可以在多个类中被new,那么就意味着可以对多个对象CopyandWriteArraryList进行addandRemove,那么如果使用带static的锁,意味着所有的copyandWriteArraryList对象被锁住了,虽说不会出错,但出现多个对象使用同一把锁,所以使用对象锁更合适,一个对象使用一个锁。

Set解决线程安全问题

原因:可以查看相关资料

HashSet是线程不安全的,底层实现HashMap,其中key作为值,Value是一个Object常量

解决办法:

  • 使用Collections
  • 使用CopyandWriteArrarySet()(底层实现CopyandWriteArraryList)

Map解决线程不安全问题

HashMap是线程不安全

原因:可以查看相关资料

解决办法:

  • Collections
  • ConcurrentHashMap

ConcurrentHashMap:

JDK1.7之前,使用分段锁

分段锁:

Hashtable之所以效率低下主要是因为其实现使用了synchronized关键字对put等操作进行加锁,而synchronized关键字加锁是对整个对象进行加锁,也就是说在进行put等修改Hash表的操作时,锁住了整个Hash表,从而使得其表现的效率低下;因此,在JDK1.5~1.7版本,Java使用了分段锁机制实现ConcurrentHashMap.

简而言之,ConcurrentHashMap在对象中保存了一个Segment数组,即将整个Hash表划分为多个分段;而每个Segment元素,即每个分段则类似于一个Hashtable;这样,在执行put操作时首先根据hash算法定位到元素属于哪个Segment,然后对该Segment加锁即可。因此,ConcurrentHashMap在多线程并发编程中可是实现多线程put操作。

缺点:并发度受Segment的个数限制

JDK1.8 

使用CAS+Synchronized保证数据安全(可以参考具体资料)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值