栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

Java内置lock锁保证线程安全的去重容器CopyOnWriteArraySet 源码解读

Java 更新时间:发布时间: 百科书网 趣学号
简介

CopyOnWriteArraySet是内置lock锁保证线程安全的去重容器CopyOnWriteArraySet

结构图:

如何保证线程安全

源码如下:

public class CopyOnWriteArrayList {
    final transient ReentrantLock lock = new ReentrantLock();
    private transient volatile Object[] array;
}

集合的本质是一个变长的数组,使用volatile修饰;add remove等操作方法使用ReentrantLock保证线程安全

add操作

源码如下:

public class CopyOnWriteArrayList {
    // 获得数组对象
    final Object[] getArray() {
        return array;
    }

    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;
            // 判断是尾插还是自定义index插入元素
            int numMoved = len - index;
            if (numMoved == 0) // 在数组末尾添加元素情况:原数组元素满了之后copy到新数组,新数组长度为原数组长度+1
                newElements = Arrays.copyOf(elements, len + 1);
            else { // 在此数组中的指定位置插入指定元素:将当前在该位置的元素(如果有)和所有后续元素向右移动(即后面元素索引+1)
                newElements = new Object[len + 1];
                System.arraycopy(elements, 0, newElements, 0, index);
                System.arraycopy(elements, index, newElements, index + 1,
                        numMoved);
            }
            // 在index位置添加新的元素
            newElements[index] = element;
            // 设置为新数组
            setArray(newElements);
        } finally {
            // 释放锁
            lock.unlock();
        }
    }

    // 设置为新数组
    final void setArray(Object[] a) {
        array = a;
    }
}
System.arraycopy()方法
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

参数解释:

  • src:源数组

  • srcPos:源数组要复制的起始位置

  • dest:目的数组

  • destPos:目的数组放置的起始位置

  • length:复制的长度

注意:

  • src 和 dest都必须是同类型或者可以进行转换类型的数组
  • 源的起始位置+长度不能超过末尾
  • 目标起始位置+长度不能超过末尾
  • 且所有的参数不能为负数
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/270298.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号