同步容器和并发容器

简介: 同步容器和并发容器

公众号merlinsea


  • 同步容器
  • 同步容器:同步容器在java中包括有Vector,HashTable,Collections.syncronizedXXX
  • 当多个线程去操作同一个同步容器的时候,调用这个同步容器的方法会持有同一把锁,在Vector中是持有this锁,在Collections.syncronizedXXX中是持有mutex锁。因此在多线程环境下可能存在线程不安全的问题
  • 下面以Vector为例作为讲解:单线程环境下使用Vector同步容器:这种用法是没有问题的,不存在线程不安全的问题。但由于Vector每一方法都使用了syncronized的关键字,在这种情况下性能不如ArrayList集合。


public class VectorDemo {
    public static void main(String[] args) {
        Vector<String> stringVector = new Vector<>();
        for (int i = 0; i < 1000; i++) {
            stringVector.add("demo" + i);
        }
        //正确迭代
        Iterator<String> stringIterator = stringVector.iterator();
        while (stringIterator.hasNext()) {
            String next = stringIterator.next();
            if (next.equals("demo2")) {
                stringIterator.remove();
            }
        }
    }
}


多线程环境下使用Vector同步容器:这种用法存在线程安全问题

640.jpg


如何保证多线程环境下操作同一个Vector依旧是线程安全的呢?

外部额外加锁。 通常会选择锁住迭代器


public class VectorDemo {
    public static void main(String[] args) {
        Vector<String> stringVector = new Vector<>();
        for (int i = 0; i < 1000; i++) {
            stringVector.add("demo" + i);
        }
        Iterator<String> stringIterator = stringVector.iterator();
        for (int i = 0; i < 4; i++) {
            new Thread(() -> {
                synchronized (stringIterator) {
                    while (stringIterator.hasNext()) {
                        String next = stringIterator.next();
                        if (next.equals("demo2")) {
                            stringIterator.remove();
                        }
                    }
                }
            }).start();
        }
    }
}


综合上述的问题,


Vector在单线程环境下不存在线程安全问题,因此不需要内部每一个方法都加syncronized修饰,因此性能不如ArrayList集合。


Vector在多线程环境下存在线程安全问题,因此外部需要额外加锁保证线程安全,但外部额外加上了syncronized修饰,syncronized代码块中的函数其实也就没有必要在加锁了,因此在多线程环境下依旧可以通过包装ArrayList实现比vector性能更好的同步容器。


以上就是Vector为啥被废弃的原因。


  • 并发容器
  • 并发容器:并发容器在java中包括有CopyOnWrite系列,Concurrent系列和BlockingQueue系列
  • 当多个线程去操作同一个并发容器的时候,会先拷贝一个并发容器的副本,然后对副本操作,最后根据cas操作进行判断然后写回原来的并发容器中。
  • 下面是多线程操作同一个CopyOnWriteArrayList的例子(线程安全)


public class Demo {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> strings = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 1000; i++) {
            strings.add("demo" + i);
        }
        for (int i = 0; i < 4; i++) {
            new Thread(() -> {
                strings.forEach(e -> {
                    if (e.equals("demo2")) {
                        /**
                         * 这里不会发生线程安全问题,remove操作是在副本中操作,然后再根据cas原理写回主存
                         */
                        strings.remove(e);
                    }
                });
            }).start();
        }
    }
}


vip算法班永久学习班: 800元/人

周一、周三、周五:8:30-9:30,周六、周日:10:30-11:30

报名方式:通过公众号导航栏的刷题群即可联系到我的微信号

vip算法班详情链接

奔跑的小梁,公众号:梁霖编程工具库算法训练营快来参加吧~
相关文章
|
4月前
|
分布式计算 DataWorks MaxCompute
DataWorks中odps到容器部署starrocks的单表同步遇到写入问题
【1月更文挑战第6天】【1月更文挑战第29篇】DataWorks中odps到容器部署starrocks的单表同步遇到写入问题
46 3
|
4月前
|
安全 Java 编译器
Java并发编程学习6-同步容器类和并发容器
【1月更文挑战第6天】本篇介绍同步容器类和并发容器的相关内容(Vector、ConcurrentHashMap、CopyOnWriteArrayList)
37 3
Java并发编程学习6-同步容器类和并发容器
|
5月前
|
分布式计算 DataWorks MaxCompute
DataWorks中odps到容器部署starrocks的单表同步遇到写入问题
DataWorks中odps到容器部署starrocks的单表同步遇到写入问题
38 1
|
12月前
|
Linux Docker 容器
Docker Review - 使用docker volume数据卷实现容器内的数据与宿主机同步
Docker Review - 使用docker volume数据卷实现容器内的数据与宿主机同步
202 0
|
12月前
|
Java 调度 容器
并发编程-15并发容器(J.U.C)核心 AbstractQueuedSynchronizer 抽象队列同步器AQS介绍
并发编程-15并发容器(J.U.C)核心 AbstractQueuedSynchronizer 抽象队列同步器AQS介绍
88 0
|
12月前
|
安全 Java 容器
并发编程-13线程安全策略之两种类型的同步容器
并发编程-13线程安全策略之两种类型的同步容器
63 0
|
4天前
|
监控 Kubernetes Docker
【Docker 专栏】Docker 容器内应用的健康检查与自动恢复
【5月更文挑战第9天】本文探讨了Docker容器中应用的健康检查与自动恢复,强调其对应用稳定性和系统性能的重要性。健康检查包括进程、端口和应用特定检查,而自动恢复则涉及重启容器和重新部署。Docker原生及第三方工具(如Kubernetes)提供了相关功能。配置检查需考虑检查频率、应用特性和监控告警。案例分析展示了实际操作,未来发展趋势将趋向更智能和高效的检查恢复机制。
【Docker 专栏】Docker 容器内应用的健康检查与自动恢复
|
1天前
|
存储 安全 开发者
如何删除 Docker 镜像、容器和卷?
【5月更文挑战第11天】
10 2
如何删除 Docker 镜像、容器和卷?
|
3天前
|
NoSQL Redis Docker
Mac上轻松几步搞定Docker与Redis安装:从下载安装到容器运行实测全程指南
Mac上轻松几步搞定Docker与Redis安装:从下载安装到容器运行实测全程指南
13 0
|
4天前
|
存储 安全 数据库
【Docker 专栏】Docker 容器内应用的状态持久化
【5月更文挑战第9天】本文探讨了Docker容器中应用状态持久化的重要性,包括数据保护、应用可用性和历史记录保存。主要持久化方法有数据卷、绑定挂载和外部存储服务。数据卷是推荐手段,可通过`docker volume create`命令创建并挂载。绑定挂载需注意权限和路径一致性。利用外部存储如数据库和云服务可应对复杂需求。最佳实践包括规划存储策略、定期备份和测试验证。随着技术发展,未来将有更智能的持久化解决方案。
【Docker 专栏】Docker 容器内应用的状态持久化