前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JUC 多线程高并发不安全集合类

JUC 多线程高并发不安全集合类

作者头像
万能青年
发布2019-08-30 14:43:51
7250
发布2019-08-30 14:43:51
举报

一、线程不安全集合在多线程操作下会出现的问题

由于ArrayList是线程不安全的,所以以ArrayList为例演示出现错误:

代码语言:javascript
复制
/**
 * @author wannengqingnian
 */
public class TestArrays {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        for (int i = 0; i <= 30; i++){
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(list);
            }).start();
        }
    }
}

运行出现:

原因:

由于 ArrayList 的 add() 方法没有加锁,多个线程同时添加数据会出现 java.util.ConcurrentModificationException 异常(并发修改异常)。

二、解决ArrayList线程不安全问题方法

1、使用new Vector<>()

Vector和ArrayList的区别是vector在add()方法上加上了synchronized关键字来保证线程安全

2、使用Collections集合工具类的Collections.SynchronizeList(new ArrayList<>());

3、使用new CopyOnWriteArrayList<> ()

三、浅解解决ArrayList线程不安全的第三种方式:CopyOnWriteArrayList

CopyOnWriteArrayList的 add() 方法底层实现:

代码语言:javascript
复制
/**
 * Appends the specified element to the end of this list.
 *
 * @param e element to be appended to this list
 * @return {@code true} (as specified by {@link Collection#add})
 */
public boolean add(E e) {
    synchronized (lock) {
        Object[] es = getArray();
        int len = es.length;
        es = Arrays.copyOf(es, len + 1);
        es[len] = e;
        setArray(es);
        return true;
    }
}

底层采用读写分离和写时复制:

CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将当前object[]进行Copy,复制出一个新的容器Object[] newElements,然后新的容器Object[] newElements里添加元素,添加完元素之后,再将原容器的引用指向新的容setArray(newElements);这样做的好处是可以对copyonwrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以copyonwrite容器也是一种读写分离的思想,读和写不同的容器。

四、HashSet线程不安全的解决

1、使用Collections集合工具类的Collections.SynchronizeList(new HashSet<>());

2、使用new CopyOnWriteHashSet<> ()

HashSet底层使用HashMap,HashSet保存数据的时候是一个值,而HashMap则是键值对。HashSet把值存到key,value则是一个常量。

五、HashMap线程不安全解决

1、使用ConcurrentHashMap<>()

2、使用Collections.synchronizedMap()

六、尾巴

解决集合线程安全问题,一般先看有没有线程安全可以替代的,没有看集合工具类中有没有提供可以保证线程安全的工具,还有CopyOnWrite中保证安全的集合。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JavaArtisan 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 底层采用读写分离和写时复制:
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档