一、基本思想
ArrayList的一个变体,通过对原来数组的拷贝,来保证不同操作情况下的线程安全。
这个容器类内部有大量的数组拷贝操作
二、源码解析
2.1 基本数据结构
/** The lock protecting all mutators */ transient final ReentrantLock lock = new ReentrantLock(); /** The array, accessed only via getArray/setArray. */ private volatile transient Object[] array;
很简单,里面一个数组而已,声明成volatile保证一个线程的修改对其它线程立即可见
2.2 get操作
public E get(int index) { return (E)(getArray()[index]); //数组的简单遍历操作,没有锁,没有拷贝 } final Object[] getArray() { return array; } public Object[] toArray()//返回的是一个数组副本 Object[] elements = getArray(); return Arrays.copyOf(elements, elements.length); }
2.3 add操作
public void add(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); //可重入锁保证线程安全 try { Object[] elements = getArray(); //获取数组对象 int len = elements.length; if (index > len || index < 0) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+len); Object[] newElements; int numMoved = len - index; if (numMoved == 0) newElements = Arrays.copyOf(elements, len + 1); //不需要移动,直接拷贝一个新的数组 else { newElements = new Object[len + 1]; System.arraycopy(elements, 0, newElements, 0, index); //拷贝待移动之前的数组 System.arraycopy(elements, index, newElements, index + 1, numMoved);//拷贝待移动的数组 } newElements[index] = element;//设置值 setArray(newElements);//将新的数组作为修改后的数组 } finally { lock.unlock();//释放锁放在final中 } }
2.4 remove 操作
public E remove(int index) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; Object oldValue = elements[index]; int numMoved = len - index - 1; if (numMoved == 0) setArray(Arrays.copyOf(elements, len - 1)); else { Object[] newElements = new Object[len - 1]; System.arraycopy(elements, 0, newElements, 0, index); System.arraycopy(elements, index + 1, newElements, index, numMoved); setArray(newElements); } return (E)oldValue; } finally { lock.unlock(); } }
很简单,和add操作基本一样
三、适用范围
官方解释,来自JDK源码中的注释。
尽管数组的大量拷贝的代价很大,但是在某些情况下可能会更加有效。比如说你需要用多个线程对数组大量的遍历,而你又不想同步你的遍历的时候。
因为你每次遍历其实是你当前数组的一个快照,所以你的程序永远不会出现"ConcurrentModifacationException"。
内存一致性问题:一个线程在处理这个数组的时候都是处理这个数组的副本,因此线程在处理过程中的这段时间,无法获得其它的线程对此数组的更改。
四、测试
//TODO :)
相关推荐
### Java多线程与并发(14-26)-JUC集合-CopyOnWriteArrayList详解 #### 一、概述 `CopyOnWriteArrayList`是一种线程安全的集合类,它是`ArrayList`的一种特殊版本,主要通过复制底层数组的方式来保证线程安全性。...
JUC提供了并发集合,如ConcurrentHashMap、ConcurrentLinkedQueue、CopyOnWriteArrayList等,它们在多线程环境下提供了高效且安全的数据结构。例如,ConcurrentHashMap在并发环境下比传统HashMap表现更优,而...
- `CopyOnWriteArrayList`和`CopyOnWriteArraySet`:读写分离的列表和集合,适合读多写少的场景,写操作时会复制一份新数组进行修改,保证读操作不被阻塞。 - `ConcurrentSkipListMap`和`ConcurrentSkipListSet`:...
这个集合提供了一系列高效、线程安全的类和接口,用于简化多线程环境下的编程任务。本资源"JUC代码收集,java高并发多线程学习"显然是一个专注于探讨和学习JUC库的资料包。 JUC库包含多个子包,如`concurrent`, `...
Java并发编程领域中,JUC(Java Concurrency Utility)库扮演着至关重要的角色,它提供了高效、安全的多线程编程工具。JUC包括线程、线程池、CAS(Compare and Swap)操作、volatile关键字以及其他相关的底层原理和...
3. **并发容器**:如ArrayList、LinkedList、Vector等线程不安全的集合,以及它们的线程安全替代品如ConcurrentHashMap、CopyOnWriteArrayList等。分析这些容器在并发环境下的性能特点和适用场景。 4. **Executor...
JUC是Java 5及后续版本引入的一个重要特性,极大地提升了Java在多处理器和高并发环境下的性能表现。 在Java中,JUC包(java.util.concurrent)包含了一系列的类和接口,这些类和接口主要用于解决并发问题,如线程池...
Collections 部分提供了一些并发集合类,例如 CopyOnWriteArrayList、ConcurrentHashMap 等,这些类可以在多线程环境下安全地使用。 3.Atomic: Atomic 部分提供了一些原子类,例如 AtomicInteger、AtomicLong 等...
- **CopyOnWriteArrayList/CopyOnWriteArraySet**:写时复制的容器,读操作无锁,写操作会创建副本,适合读多写少的场景。 - **BlockingQueue**:阻塞队列,实现生产者-消费者模型,如`ArrayBlockingQueue`、`...
JUC包包含了一系列的并发工具类,如线程池(ExecutorService)、并发集合(ConcurrentHashMap、CopyOnWriteArrayList等)、同步器(Semaphore、CountDownLatch、CyclicBarrier)以及原子类(AtomicInteger、...
为了解决这个问题,Java 提供了多种线程安全的集合类,例如 Vector、CopyOnWriteArrayList、ConcurrentHashMap 等。 Callable Callable 是 Java 中的一种函数式接口,用于描述可被线程池执行的任务。Callable 接口...
- CopyOnWriteArrayList和CopyOnWriteArraySet:读写分离的集合,写操作时复制底层数组,适用于读多写少的场景。 - ConcurrentLinkedQueue:基于链表结构的无界并发队列,采用CAS算法实现,性能较高。 - ...
JUC提供了如ConcurrentHashMap、CopyOnWriteArrayList等并发友好的集合,它们在设计上考虑了多线程环境的性能和安全性。例如,ConcurrentHashMap通过分段锁技术实现线程安全,允许并发读写,而CopyOnWriteArrayList...
JUC提供了许多线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList和CopyOnWriteArraySet。这些集合在多线程环境下能保证数据一致性,避免了传统的同步机制带来的性能损失。 5. **原子类** java.util....
7. **并发容器**:Java 提供了一些线程安全的集合框架,如 ConcurrentHashMap、CopyOnWriteArrayList 等,它们在内部已经实现了线程安全的处理,可以避免在并发操作中出现的数据不一致问题。 8. **Future 和 ...
5. Concurrent Collections:并发集合,如ConcurrentHashMap、CopyOnWriteArrayList和ConcurrentLinkedQueue等,它们在并发访问时能保证线程安全。 6. CyclicBarrier和CountDownLatch:同步辅助类,CyclicBarrier...
2. **并发集合**:包括`ConcurrentHashMap`、`ConcurrentLinkedQueue`、`CopyOnWriteArrayList`等,这些集合类在多线程环境下提供了线程安全的访问和操作。它们内部实现了高效的同步机制,避免了传统同步集合的锁粒...