Java一分钟之-高级集合框架:并发集合(Collections.synchronizedXXX)

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
大数据开发治理平台 DataWorks,不限时长
简介: 【5月更文挑战第18天】Java集合框架的`Collections.synchronizedXXX`方法可将普通集合转为线程安全,但使用时需注意常见问题和易错点。错误的同步范围(仅同步单个操作而非迭代)可能导致并发修改异常;错误地同步整个集合类可能引起死锁;并发遍历和修改集合需使用`Iterator`避免`ConcurrentModificationException`。示例代码展示了正确使用同步集合的方法。在复杂并发场景下,推荐使用`java.util.concurrent`包中的并发集合以提高性能。

在多线程环境中,共享数据的同步是至关重要的。Java集合框架提供了Collections.synchronizedXXX方法,将普通集合转换为线程安全的版本。本文将探讨这些同步集合的常见问题、易错点及如何避免,同时提供代码示例。
image.png

1. Collections.synchronizedXXX方法

Collections.synchronizedList(List<T> list), Collections.synchronizedMap(Map<K, V> map)Collections.synchronizedSet(Set<T> set) 方法分别用于创建线程安全的列表、映射和集合。这些方法将给定的集合包装在一个同步的容器中,确保在多线程环境下,对集合的操作是互斥的。

2. 常见问题与易错点

2.1 错误的同步范围

问题:只对add, get等单个操作进行同步,而忽视了迭代操作。

避免:确保整个迭代过程都在同步块内,防止并发修改异常。

2.2 错误地同步整个集合类

问题:直接同步整个集合类,而不是集合实例,这可能导致死锁。

避免:仅同步要操作的集合实例,而不是整个类。

2.3 忽略并发修改

问题:在一个线程中遍历集合,而在另一个线程中修改集合,可能导致ConcurrentModificationException

避免:在遍历期间不要修改集合,或使用Iterator进行迭代并调用iterator.remove()删除元素。

3. 代码示例

以下是一个简单的示例,展示了如何创建和使用同步集合:

import java.util.*;

public class SynchronizedCollectionsExample {
   
   
    public static void main(String[] args) {
   
   
        List<String> list = Collections.synchronizedList(new ArrayList<>());
        Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>());
        Set<String> set = Collections.synchronizedSet(new HashSet<>());

        // 正确的同步范围
        synchronized (list) {
   
   
            list.add("Item1");
            list.add("Item2");
        }

        // 错误的同步示例(易引发死锁)
        // synchronized (ArrayList.class) {
   
   
        //     list.add("Item3"); // 不要这样同步!
        // }

        // 并发迭代和修改的正确做法
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
   
   
            synchronized (list) {
   
   
                if ("Item2".equals(iterator.next())) {
   
   
                    iterator.remove(); // 使用迭代器删除元素
                }
            }
        }

        // 打印结果
        System.out.println(list);
        System.out.println(map);
        System.out.println(set);
    }
}

结论

虽然Collections.synchronizedXXX方法提供了基本的线程安全性,但它们并不适用于所有并发场景。在复杂的情况下,考虑使用java.util.concurrent包中的并发集合,如ConcurrentHashMap, CopyOnWriteArrayList等,它们提供了更高效的并发原语。始终记住,在多线程环境下,同步是必要的,但过度同步可能会导致性能下降,因此应谨慎选择同步策略。

目录
相关文章
|
18小时前
|
存储 Java
打破常规!HashSet和TreeSet教你重新认识Java集合的无序与有序
【6月更文挑战第17天】Java集合框架中的Set接口,HashSet无序而TreeSet有序。HashSet基于哈希表,元素插入顺序不可预测,适合快速去重。TreeSet利用红黑树保证有序性,支持自然排序或自定义排序。若需同时无序和有序,可先用HashSet去重,再将元素加入TreeSet,但会牺牲性能。选择时依据对顺序和性能的需求。
|
19小时前
|
算法 Java 数据处理
从HashSet到TreeSet,一场Java集合的“不重复”革命!
【6月更文挑战第17天】Java集合框架中的Set接口确保元素唯一,HashSet基于哈希表实现高效查找,不保证顺序;TreeSet使用红黑树保持排序,适用于有序场景。示例展示了HashSet的无重复添加及TreeSet的升序排列。Set是处理唯一性数据的利器。
|
20小时前
|
存储 Java 索引
告别Java集合小白!一文读懂List的精髓
【6月更文挑战第17天】Java中的List接口作为有序集合,允许存储和操作有序元素,支持重复值。ArrayList和LinkedList是常见实现类:ArrayList基于数组,适合快速访问但插入删除慢;LinkedList基于链表,插入删除快但访问慢。了解其核心概念、方法及泛型使用,能提升编程效率和代码质量。示例代码展示了添加和访问元素。通过深入学习,可以更好地掌握List的高级用法。
|
1天前
|
Java 开发者
Java中的并发编程:从基础到高级
在Java的世界里,并发编程是一块既迷人又复杂的领域。它像是一场精心编排的交响乐,需要各种乐器和乐手的协同合作。本文将带领读者走进Java并发编程的殿堂,从简单的线程创建与管理开始,逐步深入到同步机制、锁的概念,最后探索Java内存模型和高级并发工具。我们将一起揭开并发编程神秘的面纱,理解其背后的原理,并掌握如何在实际开发中有效利用这些知识来编写高效、稳定的应用程序。
|
1天前
|
Java 测试技术 C++
滚雪球学Java(63):Java高级集合之TreeSet:什么是它,为什么使用它?
【6月更文挑战第17天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
7 0
滚雪球学Java(63):Java高级集合之TreeSet:什么是它,为什么使用它?
|
2天前
|
XML 测试技术 数据格式
《手把手教你》系列基础篇(七十五)-java+ selenium自动化测试-框架设计基础-TestNG实现DDT - 中篇(详解教程)
【6月更文挑战第16天】本文介绍了TestNG中`@DataProvider`的两种使用方法。本文通过实例展示了TestNG如何利用`@DataProvider`结合方法名和`ITestContext`来灵活地为测试方法传递参数。
8 1
|
2天前
|
XML 存储 测试技术
《手把手教你》系列基础篇(七十四)-java+ selenium自动化测试-框架设计基础-TestNG实现DDT - 上篇(详解教程)
【6月更文挑战第15天】本文介绍了TestNG的数据驱动测试(Data Driven Testing, DDT)概念和好处,并提供了两个实战示例。数据驱动测试允许使用不同的测试数据执行相同的测试用例,这些数据可以从外部文件或数据库获取。这种方法提高了测试效率,减少了冗余代码,并便于应对应用程序变更。
11 0
|
3天前
|
Java
java集合
摘要:使用`equals`方法可直接比较两个集合是否完全相同,因Java集合类已重写该方法。快速创建集合可采用`Lists.newArrayList()`。
8 3
|
3天前
|
存储 算法 安全
[笔记] 疯狂JAVA讲义(第3版)第8章 Java集合(二)
[笔记] 疯狂JAVA讲义(第3版)第8章 Java集合(二)
|
3天前
|
存储 算法 Java
[笔记] 疯狂JAVA讲义(第3版)第8章 Java集合(一)
[笔记] 疯狂JAVA讲义(第3版)第8章 Java集合(一)