当前位置: 首页 > news >正文

如何在多线程环境下避免快速失败异常?

在多线程环境下,可通过以下几种方式避免快速失败(Fail-Fast)异常:

1. 使用线程安全的集合类

Java 提供了多种线程安全的集合类,它们在迭代时不会抛出 ConcurrentModificationException

示例:使用 CopyOnWriteArrayList

java

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;public class CopyOnWriteExample {public static void main(String[] args) {List<String> list = new CopyOnWriteArrayList<>();list.add("apple");list.add("banana");// 线程 1:遍历集合Thread t1 = new Thread(() -> {Iterator<String> it = list.iterator();while (it.hasNext()) {System.out.println(it.next());try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}});// 线程 2:修改集合Thread t2 = new Thread(() -> {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}list.add("cherry"); // 不会触发异常});t1.start();t2.start();}
}
常用线程安全集合
  • CopyOnWriteArrayList:适用于读多写少的场景,每次修改时会创建新数组。
  • ConcurrentHashMap:高效的线程安全 Map,支持并发读写。
  • ConcurrentLinkedQueue:无界线程安全队列,基于链表实现。

2. 使用同步机制

通过显式的同步(如 synchronized 块或 ReentrantLock)来保证同一时间只有一个线程访问集合。

示例:使用 synchronized 块

java

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class SynchronizedListExample {private static final List<String> list = new ArrayList<>();private static final Object lock = new Object();public static void main(String[] args) {list.add("apple");list.add("banana");// 线程 1:遍历集合Thread t1 = new Thread(() -> {synchronized (lock) {Iterator<String> it = list.iterator();while (it.hasNext()) {System.out.println(it.next());}}});// 线程 2:修改集合Thread t2 = new Thread(() -> {synchronized (lock) {list.add("cherry");}});t1.start();t2.start();}
}
注意事项
  • 同步会导致性能下降,尤其在读操作频繁时。
  • 需要确保所有对集合的访问都使用相同的锁。

3. 使用 Collections.synchronizedList() 包装集合

将普通集合转换为同步集合,但迭代时仍需手动同步。

示例:

java

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;public class SynchronizedWrapperExample {public static void main(String[] args) {List<String> list = Collections.synchronizedList(new ArrayList<>());list.add("apple");list.add("banana");// 迭代时必须手动同步synchronized (list) {Iterator<String> it = list.iterator();while (it.hasNext()) {System.out.println(it.next());}}// 修改操作会自动同步list.add("cherry");}
}

4. 使用并发友好的迭代方式

某些并发集合提供了弱一致性(Weakly Consistent)的迭代器,允许在迭代过程中修改集合。

示例:ConcurrentHashMap 的弱一致性迭代器

java

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;public class ConcurrentHashMapExample {public static void main(String[] args) {ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();map.put("apple", 1);map.put("banana", 2);// 弱一致性迭代器允许并发修改Iterator<String> it = map.keySet().iterator();while (it.hasNext()) {String key = it.next();System.out.println(key);map.put("cherry", 3); // 不会抛出异常}}
}

根据具体业务场景选择合适的方案,优先考虑使用 Java 提供的并发集合类,避免手动同步带来的复杂性。

http://www.xdnf.cn/news/457615.html

相关文章:

  • VMware(Ubuntu系统)设置共享文件夹
  • 前端流行框架Vue3教程:16. 组件事件配合`v-model`使用
  • 阿里云ECS部署Dify
  • go依赖查询工具之godepgraph(分析main.go的依赖树)
  • 机器学习08-损失函数
  • 【上位机——WPF】Window标签常用属性
  • 概率相关问题
  • win10电脑无法访问局域网内其他共享电脑文件的问题
  • 用C语言实现了——一个基于顺序表的插入排序演示系统
  • Java并发编程:锁机制
  • 数据库--处理模型(Processing Model)(二)
  • AWS CloudHSM:金融级密钥安全管理实战,如何通过FIPS 140-2认证守护数据生命线?
  • aws 实践创建policy + Role
  • 黑马程序员c++2024版笔记 第一章
  • Delphi 中 BPL(2):大型项目中 BPL 对性能的影响及调优策略
  • 2025年11月软考各科目难度及适合人群分析
  • 浪潮云边协同:赋能云计算变革的强力引擎
  • YOLO11改进-模块-引入空间增强前馈网络SEFN 提高多尺度 遮挡
  • 华宇TAS应用中间件与亿信华辰多款软件产品完成兼容互认证
  • 2025 OceanBase 开发者大会全议程指南
  • 【AI论文】用于评估和改进大型语言模型中指令跟踪的多维约束框架
  • 如何卸载并重新安装 Mozilla Firefox 浏览器
  • 2025年,多模态特征融合只会更火
  • 基于Rust语言的Rocket框架和Sqlx库开发WebAPi项目记录(一)
  • WPS文字的“邮件合并”功能-----批量生成word文档
  • 一文讲透 Vue3 + Three.js 材质属性之皮革篇【扫盲篇】
  • 【hadoop】sqoop案例 hive->mysql
  • 2.ch452a 4线驱动按键扫描
  • Spring MVC 拦截器 (HandlerInterceptor) 是什么? 它与 Servlet Filter 有什么区别?
  • Kotlin并发请求的一些知识记录