Java并发编程之-list集合的并发.
我们都知道Java集合类中的arrayList是线程不安全的。那么怎么证明是线程不安全的呢?怎么解决在并发环境下使用安全的list集合类呢?
本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《并发集合系列》教程的第一篇:
本文主要内容:怎么证明arrayList不是线程安全的?怎么解决这个问题?以及遇到问题解决的四个步骤及从源码来分析作者思路。
一:怎么证明arrayList在并发情况下是线程不安全的呢?
创建一个list,用多个线程向list中添加数据。来看看结果
查看运行结果:
我们发现了一个异常:java.util.ConcurrentModificationException
java.util.ConcurrentModificationException是什么
这个异常什么意思呢?我们来看看这个异常源码中类的注释信息:
This exception may be thrown by methods that have detected concurrent(此异常可能由检测到并发的方法引发).
一般可以理解为,这是并发导致的异常。那么在并发情况下出现了异常。是不是从侧面说明arrayList是不安全的呢?
二:怎么解决这个问题
这里凯哥顺便说下,解决问题的一般步骤。
1:怎么操作导致的故障及现象是什么?
操作:多个线程对list进行add添加操作的时候
结果:抛出了java.util.ConcurrentModificationException异常信息
2:分析产生这个问题的原因
举个现实生活中的例子。签到表,这个大家都见过吧,应该都签到过吧。比如现在有个会议很多人来参与,需要签到。现在,司小司正在签到表上写自己的名字时候,小明非要看签到表上面有没有自己名字。因为司小司正在签到进行中,小明硬是要查看,把签到表抢过去,结果就是签到表被撕坏了或者是司小司的笔在签到表上留下了长长的痕迹。如果上面这个例子用计算机角度分析的话。
两个线程(司小司和小明)对一个共享变量(签到表,可以理解为是人名的集合)进行读写操作(司小司签到是写操作,小明要查看自己是否签到了,可以理解为读操作),因为两个线程都来竞争共享资源。后果就是签到表被撕坏了或者是司小司的笔在签到表上留下了长长的痕迹。异常现象。用到上面我们多个线程对list进行操作的时候,就抛异常了多线程并发修改异常信息。
3:解决方案是什么?
1:使用线程安全的List的子类Vectory
List list = new Vectory();
查看vectory的add方法源码:
发现,原来vector的add方法是加的并发锁来保证线程安全的
2:使用collections工具类的sync方法
List list = Colletcions.synchronizedList(new ArrayList<>());
查看源码:
原来都是synchronized的。
我们在来看看synchronizedList方法上面的注释。
发现,原来源码中是把整个list对象作为同步锁的锁。这样来保证线程安全的
4:解决方案可以优化吗?优化的建议是什么?
我们知道synchronized关键字是同步锁机制。强制并行转化成串行的一种方案。这种对性能消耗比较大。有没有更其他可以优化的方案吗?
来看看使用JUC并发包下的:CopyOnWriteArrayList(写时复制list)来解决吧。
先来看看这个类的add方法的源码:
从源码中,我们可以看到复制了一个新的list集合,将新元素在新集合中操作。那么为什么这种操作就不会出现并发异常呢?
因为这种思想,可以理解为读写分离的思想。因为get还是使用原来list的get的方法。写的时候,在复制一份原来的,然后再复制出来的基础上进行修改的。那么怎么保证数据问题呢?我们从源码中可以看到使用到了ReentrantLock(关于锁相关的。凯哥(凯哥Java:kaigejava)将在后面详细的讲解的)锁来控制的。
那么现在使用CopyOnWriteArrayList来模拟下文章开头签到例子。
司小司再签到的时候,先把签到表复制一份,然后再新的复制出来的签到表中进行签到。小明是原来签到表查看自己的信息的。这样就不会出现争强情况了。
相关推荐
### JAVA并发编程实践 #### 一、并发编程基础 ##### 1.1 并发与并行的区别 在Java并发编程中,“并发”与“并行”是两个容易混淆的概念。简单来说,并发是指多个任务在同一时间段内交替执行,而并行则是指多个任务...
这个范例涵盖了Java并发编程的基础,但实际项目可能涉及更复杂的并发控制,如线程池、Future、Callable、CyclicBarrier、CountDownLatch等。通过学习和实践这些范例,开发者可以逐步掌握Java并发编程的核心概念和...
JAVA提供了丰富的API来支持多线程编程,如Thread类和Runnable接口。通过创建和管理线程,开发者可以设计出能够充分利用多核处理器性能的应用。线程同步是多线程编程中的难点,包括synchronized关键字、wait/notify...
在Java编程中,"list集合树状排序"是一种常见的需求,特别是在处理前端展示的数据时,如使用jQuery的treetable插件。这个场景通常涉及到数据结构的组织和排序,以便前端能够按照树形结构正确地展示层级关系。下面将...
7. **集合框架**:Java集合框架包括List、Set、Queue和Map等接口,以及ArrayList、HashSet、LinkedList、HashMap等实现类,用于存储和管理对象。理解它们的区别和应用场景是Java编程的关键。 8. **输入输出流**:...
Java编程基础笔记主要聚焦在集合框架上,这是Java编程中不可或缺的部分。集合框架是Java提供的一组接口和类,用于存储和操作数据。它包括两种主要类型:Collection和Map。 Collection是所有单值容器的超接口,其中...
3. **集合框架**:Java集合框架是处理对象集合的重要工具,包括List、Set、Queue、Map等接口以及ArrayList、LinkedList、HashSet、HashMap等实现。书中会详细介绍它们的特性和使用场景,以及如何高效地操作集合。 4...
Java集合框架是Java编程语言中不可或缺的一部分,它提供了一种高效组织和管理对象的方式。这份资源详细讲解了Java集合框架的各个方面,旨在帮助开发者更好地理解和使用集合。 首先,集合框架中的`Collection`接口是...
7. **集合框架**:Java2引入了丰富的集合框架,包括List、Set、Map等接口,以及ArrayList、LinkedList、HashSet、HashMap等实现类,提供高效的数据存储和操作。 8. **输入/输出流**:Java的IO流系统支持对文件、...
6. **集合框架**:Java集合框架包括List、Set、Map等接口及其实现类,如ArrayList、LinkedList、HashSet、HashMap等。这些例子会介绍如何创建和操作这些集合,以及如何使用泛型提高代码的类型安全性。 7. **多线程*...
项目中可能还涉及线程(Thread)和并发编程,这是多任务处理的关键。Java提供Thread类支持多线程,还有synchronized关键字和volatile修饰符来处理并发问题,确保数据的一致性。 集合框架(Collections Framework)...
4. **并发集合**:`03-并发List、Set、ConcurrentHashMap底层原理剖析-monkey`涵盖了Java并发集合的讨论。ConcurrentHashMap是一种线程安全的哈希映射表,相比synchronized Map,它提供了更高的并发性和更少的锁定。...
5. **多线程编程**:Java支持并发编程,使得程序能够同时执行多个任务。书中会介绍Thread类、Runnable接口,以及同步机制如synchronized关键字和Lock接口。 6. **输入/输出与网络编程**:Java提供了丰富的I/O流和...
并发编程是Java2的重要特性,尤其是从Java 5开始引入的并发工具类和并发集合。线程的创建、同步、互斥和死锁的避免等概念会在书中得到详尽解释。另外,Java内存模型(JMM)和volatile关键字也是理解多线程安全的关键...
4. **Java并发**:Java提供了丰富的并发编程工具,如线程池、synchronized、volatile、ThreadLocal、Lock等。理解并发编程原理,掌握如何在多线程环境中保证数据一致性,防止死锁、活锁和饥饿现象,是编写高效、稳定...
5. **多线程**:Java提供了强大的多线程支持,通过Thread类和Runnable接口可以创建并运行多个线程,同时学习同步机制(如synchronized关键字、wait/notify机制)防止并发访问导致的数据不一致。 6. **网络编程**:...
集合框架是Java中存储和管理对象的工具,包括List、Set、Queue和Map等接口,以及ArrayList、LinkedList、HashSet、HashMap等实现。了解它们的特点和使用场景,以及泛型和并发容器(如ConcurrentHashMap)的运用,能...
16. **并发编程**:Java并发库中的并发工具类,如CountDownLatch、Semaphore、CyclicBarrier等。 17. **Lambda表达式**:Java 8引入的新特性,简化函数式编程。 18. **Stream API**:处理集合的新方式,提供链式...
4. **集合框架**:Java集合框架包括List、Set、Map等接口及其实现类,如ArrayList、LinkedList、HashSet、HashMap等。通过实践,你可以了解到它们各自的特点和使用场景。 5. **多线程**:Java提供了丰富的多线程...