`
tmj_159
  • 浏览: 705874 次
  • 性别: Icon_minigender_1
  • 来自: 永州
社区版块
存档分类
最新评论

juc 下的集合之六 (CopyOnWriteArrayList )

 
阅读更多

一、基本思想

       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详解.pdf

    ### Java多线程与并发(14-26)-JUC集合-CopyOnWriteArrayList详解 #### 一、概述 `CopyOnWriteArrayList`是一种线程安全的集合类,它是`ArrayList`的一种特殊版本,主要通过复制底层数组的方式来保证线程安全性。...

    JUC线程锁框架

    JUC提供了并发集合,如ConcurrentHashMap、ConcurrentLinkedQueue、CopyOnWriteArrayList等,它们在多线程环境下提供了高效且安全的数据结构。例如,ConcurrentHashMap在并发环境下比传统HashMap表现更优,而...

    Java——JUC

    - `CopyOnWriteArrayList`和`CopyOnWriteArraySet`:读写分离的列表和集合,适合读多写少的场景,写操作时会复制一份新数组进行修改,保证读操作不被阻塞。 - `ConcurrentSkipListMap`和`ConcurrentSkipListSet`:...

    JUC代码收集,java高并发多线程学习

    这个集合提供了一系列高效、线程安全的类和接口,用于简化多线程环境下的编程任务。本资源"JUC代码收集,java高并发多线程学习"显然是一个专注于探讨和学习JUC库的资料包。 JUC库包含多个子包,如`concurrent`, `...

    JUC并发编程与源码分析视频课.zip

    3. **并发容器**:如ArrayList、LinkedList、Vector等线程不安全的集合,以及它们的线程安全替代品如ConcurrentHashMap、CopyOnWriteArrayList等。分析这些容器在并发环境下的性能特点和适用场景。 4. **Executor...

    heima-JUC-资料

    JUC是Java 5及后续版本引入的一个重要特性,极大地提升了Java在多处理器和高并发环境下的性能表现。 在Java中,JUC包(java.util.concurrent)包含了一系列的类和接口,这些类和接口主要用于解决并发问题,如线程池...

    Java 多线程与并发(7-26)-JUC - 类汇总和学习指南.pdf

    Collections 部分提供了一些并发集合类,例如 CopyOnWriteArrayList、ConcurrentHashMap 等,这些类可以在多线程环境下安全地使用。 3.Atomic: Atomic 部分提供了一些原子类,例如 AtomicInteger、AtomicLong 等...

    juc从入门到精通实例代码.rar

    - **CopyOnWriteArrayList/CopyOnWriteArraySet**:写时复制的容器,读操作无锁,写操作会创建副本,适合读多写少的场景。 - **BlockingQueue**:阻塞队列,实现生产者-消费者模型,如`ArrayBlockingQueue`、`...

    谈一谈对JUC的理解Java系列2021.pdf

    JUC包包含了一系列的并发工具类,如线程池(ExecutorService)、并发集合(ConcurrentHashMap、CopyOnWriteArrayList等)、同步器(Semaphore、CountDownLatch、CyclicBarrier)以及原子类(AtomicInteger、...

    Java-JUC-多线程 进阶

    为了解决这个问题,Java 提供了多种线程安全的集合类,例如 Vector、CopyOnWriteArrayList、ConcurrentHashMap 等。 Callable Callable 是 Java 中的一种函数式接口,用于描述可被线程池执行的任务。Callable 接口...

    JUC包含线程,线程池,CAS,volatile等底层原理,以及相关问题的解决方式以及相关工具类的使用

    Java并发编程领域中,JUC(Java Concurrency Utility)库扮演着至关重要的角色,它提供了高效、安全的多线程编程工具。JUC包括线程、线程池、CAS(Compare and Swap)操作、volatile关键字以及其他相关的底层原理和...

    JUC

    - CopyOnWriteArrayList和CopyOnWriteArraySet:读写分离的集合,写操作时复制底层数组,适用于读多写少的场景。 - ConcurrentLinkedQueue:基于链表结构的无界并发队列,采用CAS算法实现,性能较高。 - ...

    JUC-High-Concurrency:java.util.concurrent JUC高并发处理

    JUC提供了如ConcurrentHashMap、CopyOnWriteArrayList等并发友好的集合,它们在设计上考虑了多线程环境的性能和安全性。例如,ConcurrentHashMap通过分段锁技术实现线程安全,允许并发读写,而CopyOnWriteArrayList...

    juc-learn:juc相关源码的分析以及使用介绍

    JUC提供了许多线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList和CopyOnWriteArraySet。这些集合在多线程环境下能保证数据一致性,避免了传统的同步机制带来的性能损失。 5. **原子类** java.util....

    JUC面试知识点总结1

    7. **并发容器**:Java 提供了一些线程安全的集合框架,如 ConcurrentHashMap、CopyOnWriteArrayList 等,它们在内部已经实现了线程安全的处理,可以避免在并发操作中出现的数据不一致问题。 8. **Future 和 ...

    jvm-juc:jvm学习笔记

    5. Concurrent Collections:并发集合,如ConcurrentHashMap、CopyOnWriteArrayList和ConcurrentLinkedQueue等,它们在并发访问时能保证线程安全。 6. CyclicBarrier和CountDownLatch:同步辅助类,CyclicBarrier...

    JUC:Java util并发

    2. **并发集合**:包括`ConcurrentHashMap`、`ConcurrentLinkedQueue`、`CopyOnWriteArrayList`等,这些集合类在多线程环境下提供了线程安全的访问和操作。它们内部实现了高效的同步机制,避免了传统同步集合的锁粒...

Global site tag (gtag.js) - Google Analytics