并发编程-13线程安全策略之两种类型的同步容器

简介: 并发编程-13线程安全策略之两种类型的同步容器

2019080611330380.jpg


脑图

20190223152151128.png



概述


上篇 并发编程-12线程安全策略之常见的线程不安全类讲了一些常用的线程不安全的集合容器(ArrayList、HashMap、HashSet),如果有多个线程并发访问这些集合时就会出现线程不安全的问题。 当我们在使用这些容器时,需要我们自己来处理线程安全的问题。 使用起来相对会有些不便,而Java在这方面提供了相应的同步容器,我们可以在多线程情况下可以结合实际场景考虑使用这些同步容器。


同步容器


20190223154601865.png


集合接口下的同步容器实现类

  • Vector的方法都是由synchronized关键字保护


2019022315483053.png



20190223155014932.png

ctrl + o,方法左侧,就可以看出是个同步方法。


Stack继承了Vector,并且提供了栈操作(先进后出)

20190223154514708.png


Hashtable也是由synchronized关键字保护


20190223154718914.png


Vector (线程安全性比ArrayList好一些,但并非绝对线程安全)

ArrayList线程不安全的例子:

https://blog.csdn.net/yangshangwei/article/details/87887613#ArrayList__121


20190223155442315.png

运行结果:

20190223155502579.png


这种情况下 ,多线程 计算结果正确


同步容器 线程不安全的场景


同步容器也并不一定是绝对线程安全的,例如有两个线程,线程A根据size的值循环执行remove操作,而线程B根据size的值循环执行执行get操作。它们都需要调用size获取容器大小,当循环到最后一个元素时,若线程A先remove了线程B需要get的元素,那么就会报越界错误


Vector中的方法都进行了同步处理,那么一定就是线程安全的,事实上这可不一定 。来演示下


20190223170301268.png

运行结果: java.lang.ArrayIndexOutOfBoundsException

20190223170458160.png

我们来分析一下:

Vector是线程安全的,为什么还会报这个错?对于Vector,虽然能保证每一个时刻只能有一个线程访问它,但是不排除这种可能:


当某个线程在某个时刻执行这句时:

for(int i=0;i<vector.size();i++){
   vector.get(i);
}

假若此时vector的size方法返回的是10,i的值为9

然后另外一个线程执行了这句:

for(int i=0;i<vector.size();i++){
  vector.remove(i);
}


将下标为9的元素删除了, 那么通过get方法访问下标为9的元素肯定就会出问题了。

因此为了保证线程安全,必须在方法调用端做额外的同步措施


20190223171737984.png

其他注意事项

当我们使用foreach循环或迭代器去遍历元素的同时又执行删除操作的话,即便在单线程下也会报并发修改异常.

20190223233636866.png


所以在foreach循环或迭代器遍历的过程中不能做删除操作,若需遍历的同时进行删除操作的话尽量使用for循环。实在要使用foreach循环或迭代器的话应该先标记要删除元素的下标,然后最后再统一删除. 如果使用JDK8,可以使用函数式编程

20190223172919779.png


Hashtable

线程不安全的HashMap

https://blog.csdn.net/yangshangwei/article/details/87887613#HashMap__130


20190223173501543.png

运行结果:


20190223173521866.png


Collections.synchronizedXXX方法所创建的同步容器


Collections类中提供了多个synchronizedXxx方法, 该方法返回指定集合对象对应的同步对象,从而可以解决多线程并发访问集合时的线程安全问题


20190223213937663.png


Collections.synchronizedList


20190223220338336.png


运行结果: 线程安全

20190223220559457.png


Collections.synchronizedMap



20190223220703524.png


运行结果: 线程安全

20190223220718714.png

Collections.synchronizedSet


2019022322080175.png


运行结果: 线程安全


20190223220812469.png

小结


同步容器是通过synchronized来实现同步的,所以性能较差。而且同步容器也并不是绝对线程安全的,在一些特殊情况下也会出现线程不安全的行为。那么有没有更好的方式代替同步容器呢?----> 那就是**并发容器,有了并发容器后同步容器的使用也越来越少的,大部分都会优先使用并发容器(J.U.C)**. 下篇博文我们讨论下J.U.C


总之一句话,优先使用并发容器提供的集合,而不是使用加了锁的同步容器中的集合


代码


https://github.com/yangshangwei/ConcurrencyMaster

相关文章
|
1月前
|
运维 Kubernetes 监控
构建高效自动化运维系统:基于容器技术的策略与实践
【4月更文挑战第19天】随着云计算和微服务架构的兴起,传统的运维模式正逐渐向自动化、智能化转型。本文将探讨如何利用容器技术构建一个高效、可靠的自动化运维系统,涵盖系统设计原则、关键技术选型以及实践经验分享。通过引入容器技术,我们可以实现应用的快速部署、弹性伸缩和故障自愈,从而提高运维效率,降低系统维护成本。
|
20天前
|
存储 Kubernetes Cloud Native
【阿里云云原生专栏】云原生容器存储:阿里云CSI与EBS的高效配合策略
【5月更文挑战第29天】阿里云提供云原生容器存储接口(CSI)和弹性块存储(EBS)解决方案,以应对云原生环境中的数据存储挑战。CSI作为Kubernetes的标准接口简化存储管理,而EBS则提供高性能、高可靠性的块存储服务。二者协同实现动态供应、弹性伸缩及数据备份恢复。示例代码展示了在Kubernetes中使用CSI和EBS创建存储卷的过程。
81 3
|
1月前
|
存储 安全 数据安全/隐私保护
【Docker 专栏】Docker 容器化应用的备份与恢复策略
【5月更文挑战第9天】本文探讨了Docker容器化应用的备份与恢复策略,强调了备份在数据保护、业务连续性和合规要求中的关键作用。内容涵盖备份的重要性、内容及方法,推荐了Docker自带工具和第三方工具如Portainer、Velero。制定了备份策略,包括频率、存储位置和保留期限,并详细阐述了恢复流程及注意事项。文章还提及案例分析和未来发展趋势,强调了随着技术发展,备份与恢复策略将持续演进,以应对数字化时代的挑战。
【Docker 专栏】Docker 容器化应用的备份与恢复策略
|
12天前
|
安全 Java 大数据
Java性能优化(七)-多线程调优-并发容器的使用
Java性能优化(七)-多线程调优-并发容器的使用
18 0
|
17天前
|
存储 Kubernetes Linux
pod介绍之 容器分类与重启策略
pod介绍之 容器分类与重启策略
|
21天前
|
监控 安全 云计算
云端防御战线:云计算环境下的网络安全策略构建高效稳定的Docker容器监控体系
【5月更文挑战第27天】 在数字化时代的浪潮中,云计算已成为企业与个人存储和处理数据的重要平台。然而,随着云服务使用率的飙升,网络威胁也愈发狡猾且复杂。本文将深入探讨在云计算环境中维护网络安全的挑战及策略,重点分析信息安全的关键组成部分,并提出多层次防御模型以增强云环境的数据保护能力。通过剖析最新的安全技术与实践,我们旨在为读者提供一套全面的网络安全解决方案蓝图。
|
22天前
|
运维 监控 Kubernetes
构建高效自动化运维体系:基于容器技术的持续部署策略
【5月更文挑战第27天】 在现代IT基础设施的管理中,自动化运维已成为提升效率、保障稳定性的关键因素。本文将探讨如何利用容器技术实现服务的快速部署和可靠运行,以及构建一个高效的自动化运维体系。通过深入分析容器化的优势与挑战,并提出一个切实可行的持续部署策略,旨在帮助运维团队优化现有流程,应对快速变化的业务需求。
|
1月前
|
安全 Java 容器
Java一分钟之-并发编程:并发容器(ConcurrentHashMap, CopyOnWriteArrayList)
【5月更文挑战第18天】本文探讨了Java并发编程中的`ConcurrentHashMap`和`CopyOnWriteArrayList`,两者为多线程数据共享提供高效、线程安全的解决方案。`ConcurrentHashMap`采用分段锁策略,而`CopyOnWriteArrayList`适合读多写少的场景。注意,`ConcurrentHashMap`的`forEach`需避免手动同步,且并发修改时可能导致`ConcurrentModificationException`。`CopyOnWriteArrayList`在写操作时会复制数组。理解和正确使用这些特性是优化并发性能的关键。
25 1
|
1月前
|
监控 安全 数据安全/隐私保护
【Docker专栏】Docker容器安全:防御与加固策略
【5月更文挑战第7天】本文探讨了Docker容器安全,指出容器化技术虽带来便利,但也存在安全隐患,如不安全的镜像、容器逃逸、网络配置不当等。建议采取使用官方镜像、镜像扫描、最小权限原则等防御措施,并通过安全的Dockerfile编写、运行时安全策略、定期更新和访问控制等加固容器安全。保持警惕并持续学习安全实践至关重要。
【Docker专栏】Docker容器安全:防御与加固策略
|
1月前
|
JSON 机器人 Linux
Docker_volume(容器和宿主同步数据)
Docker_volume(容器和宿主同步数据)
23 2

热门文章

最新文章