多线程应用提高(IV) 线程安全的集合类

  created  by  鱼鱼 {{tag}}
创建于 2019年07月13日 01:08:28 最后修改于 2019年07月13日 18:59:21
评论区
评论
{{comment.creator}}
{{comment.createTime}} {{comment.index}}楼
评论

多线程应用提高(IV) 线程安全的集合类

多线程应用提高(IV) 线程安全的集合类

        在Java中的数据结构一篇中,列举了Java中一些常见的集合,此文主要梳理线程安全的相关集合。

相关概念

线程安全

        我们知道,当一个实例对象只能被一个线程访问时(线程私有),无论如何都不会有线程安全的问题,但在多线程的情境下,多个线程操作同一个对象时,可能会出现更新丢失、读写数据不同步、计数击穿等现象,此时这种操作就是非线程安全的。相应地,线程安全的集合有这样的特点:在多个线程操作同一集合时,能保证每一步操作都是安全的,与串行执行的结果一致,不会出现数据不同步等预料之外的问题。

快速失败与安全失败

        可以先看这个小例子Java-lab/ListT.java at master · fishstormX/Java-lab,我在里面解释了

        在迭代常用但是不保证线程安全的集合时,每次对集合的修改都会导致抛出ConcurrentModificationException异常,此处的修改指插入和删除操作,修改某个元素不会导致抛出这种异常(list.set(int,object)或是map的已有键值对覆盖),抛出这种异常的机制叫做快速失败(fail-fast),主要是依赖modConut统计修改次数,一旦迭代开始记录的modCount不等于当前的modCount,便会发生快速失败终止迭代。因为util包下线程不安全的集合类都是在实体对象上直接进行迭代这能最大限度的防止发生线程安全的问题,但由于modCount自加的操作与其他操作不具有原子性,一就会有概率发生安全问题。

        相对应的,线程安全的集合类采用安全失败(fail-safe),它所迭代的是原集合对象的副本,所以你可以在本线程或是其他线程随意修改集合而不会抛出异常,当然,你所做的任何改变对于当前的迭代时不可见的。

并发集合与同步集合

        所谓的并发集合指java.util.concurrent包下的集合,例如最常见的ConcurrentHashMap、CopyOnWriteArrayList,而同步集合则是指Vector、HashTable以及通过调用Collections.synchronizedMap、Collections.synchronizedList、Collections.synchronizedSet转换出的集合对象。实际应用中,除非有特殊要求(比如需要一个同步的LinkedHashMap),一般很少使用同步集合,因其性能相对较低。

线程安全≠逻辑同步

//TODO

        


2019-07-13鱼鱼

{{commentTitle}}

评论   ctrl+Enter 发送评论