【JUC】JDK1.8源码分析之CopyOnWriteArraySet(七)

简介: 分析完了CopyOnWriteArrayList后,下面接着分析CopyOnWriteArraySet,CopyOnWriteArraySet与CopyOnWriteArrayList有莫大的联系,因为CopyOnWriteArraySet的底层是由CopyOnWriteArrayList提供支持,并且将对其的操作转发至对CopyOnWriteArrayList的操作。但是,CopyOnWriteArraySet的元素不允许重复,这是和CopyOnWriteArrayList不相同的地方,下面开始分析。

一、前言


  分析完了CopyOnWriteArrayList后,下面接着分析CopyOnWriteArraySet,CopyOnWriteArraySet与CopyOnWriteArrayList有莫大的联系,因为CopyOnWriteArraySet的底层是由CopyOnWriteArrayList提供支持,并且将对其的操作转发至对CopyOnWriteArrayList的操作。但是,CopyOnWriteArraySet的元素不允许重复,这是和CopyOnWriteArrayList不相同的地方,下面开始分析。


二、CopyOnWriteArraySet数据结构


  由于CopyOnWriteArraySet底层是使用CopyOnWriteArrayList,所以其数据结构与CopyOnWriteArrayList相同,采用数组结构。其结构如下

download.png

 说明:CopyOnWriteArraySet由于是基于CopyOnWriteArrayList的,所以对其操作都是基于CopyOnWriteArrayList的,其中所有可变操作(add、set 等等)都是通过对底层数组进行一次新的复制来实现的。


三、CopyOnWriteArraySet源码分析


3.1 类的继承关系 

public class CopyOnWriteArraySet<E> extends AbstractSet<E>
        implements java.io.Serializable {}

说明:CopyOnWriteArraySet继承了AbstractSet抽象类,AbstractSet提供 Set 接口的骨干实现,从而最大限度地减少了实现此接口所需的工作;同时实现了Serializable接口,表示可以序列化。


  3.2 类的属性  

public class CopyOnWriteArraySet<E> extends AbstractSet<E>
        implements java.io.Serializable {
    // 版本序列号
    private static final long serialVersionUID = 5457747651344034263L;
    // 由其对CopyOnWriteArraySet提供支持
    private final CopyOnWriteArrayList<E> al;
}

 说明:其属性中包含了一个CopyOnWriteArrayList类型的变量al,对CopyOnWriteArraySet的操作会转发至al上执行。


  3.3 类的构造函数


  1. CopyOnWriteArraySet()型构造函数 

  public CopyOnWriteArraySet() {
        // 初始化al
        al = new CopyOnWriteArrayList<E>();
    }

 说明:此构造函数用于创建一个空 set。


  2. CopyOnWriteArraySet(Collection<? extends E>)型构造函数

 public CopyOnWriteArraySet(Collection<? extends E> c) {
        if (c.getClass() == CopyOnWriteArraySet.class) { // c集合为CopyOnWriteArraySet类型
            // 初始化al
            @SuppressWarnings("unchecked") CopyOnWriteArraySet<E> cc =
                (CopyOnWriteArraySet<E>)c;
            al = new CopyOnWriteArrayList<E>(cc.al);
        }
        else { // c集合不为CopyOnWriteArraySet类型
            // 初始化al
            al = new CopyOnWriteArrayList<E>();
            // 添加c集合(c集合的元素在al中部存在时,才会添加)
            al.addAllAbsent(c);
        }
    }

 说明:此构造函数用于创建一个包含指定 collection 所有元素的 set。处理流程如下

  

① 判断集合c的类型是否为CopyOnWriteArraySet类型,若是,则获取c的al,并且初始当前CopyOnWriteArraySet的al域(调用CopyOnWriteArrayList的构造函数),否则,进入步骤②


  ② 新生CopyOnWriteArrayList,并赋值给al,之后调用addAllIfAbsent函数(al中不存在的元素,才添加)。


  3.4 核心函数分析


  由于对CopyOnWriteArraySet的操作(如add、remove、clear等)都转化为对CopyOnWriteArrayList的操作,所以在此不再进行讲解,有疑惑的读者可以参考CopyOnWriteArrayList的源码分析。


四、示例


  下面通过一个示例来了解CopyOnWriteArraySet的使用。 

package com.hust.grid.leesf.collections;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;
class PutThread extends Thread {
    private CopyOnWriteArraySet<Integer> cowas;
    public PutThread(CopyOnWriteArraySet<Integer> cowas) {
        this.cowas = cowas;
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            cowas.add(i);
        }
    }
}
public class CopyOnWriteArraySetDemo {
    public static void main(String[] args) {
        CopyOnWriteArraySet<Integer> cowas = new CopyOnWriteArraySet<Integer>();
        for (int i = 0; i < 10; i++) {
            cowas.add(i);
        }
        PutThread p1 = new PutThread(cowas);
        p1.start();
        Iterator<Integer> iterator = cowas.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
        System.out.println();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        iterator = cowas.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
    }

运行结果(某一次) 

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 

说明:首先,主线程向CopyWriteArraySet也添加了元素,然后,PutThread线程向CopyOnWriteArraySet中添加元素(与之前添加了元素重复),两次迭代,遍历集合,发现结果相同,即CopyWriteArraySet中没有重复的元素。


五、总结


  CopyOnWriteArraySet的源码比较简单,是依托CopyOnWriteArrayList而言,所以当分析完了CopyOnWriteArrayList后,CopyOnWriteArraySet的分析就非常简单,谢谢各位园友的观看~

目录
相关文章
|
7月前
|
存储 安全 Java
【JDK 源码分析】ConcurrentHashMap 底层结构
【1月更文挑战第27天】【JDK 源码分析】ConcurrentHashMap 底层结构
|
7月前
|
Java
【JDK 源码分析】HashMap 操作方法
【1月更文挑战第27天】【JDK 源码分析】HashMap Put 元素 初始化
|
7月前
|
存储 网络协议 Java
【Java】BIO源码分析和改造(GraalVM JDK 11.0.19)(二)
【Java】BIO源码分析和改造(GraalVM JDK 11.0.19)
81 0
【Java】BIO源码分析和改造(GraalVM JDK 11.0.19)(二)
|
7月前
|
Java
Integer类【JDK源码分析】
Integer类【JDK源码分析】
49 0
源码分析系列教程(12) - 手写Map框架(基于JDK1.7)
源码分析系列教程(12) - 手写Map框架(基于JDK1.7)
38 0
|
2月前
|
Java
Java基础之 JDK8 HashMap 源码分析(中间写出与JDK7的区别)
这篇文章详细分析了Java中HashMap的源码,包括JDK8与JDK7的区别、构造函数、put和get方法的实现,以及位运算法的应用,并讨论了JDK8中的优化,如链表转红黑树的阈值和扩容机制。
32 1
|
6月前
|
存储 算法 安全
JDK源码分析-HashMap
JDK源码分析-HashMap
|
算法 搜索推荐 Java
Arrays类【JDK源码分析】
Arrays类【JDK源码分析】
56 0
|
安全 Java API
StringBuilder类【JDK源码分析】
StringBuilder类【JDK源码分析】
88 0
|
Java API 索引
LinkedList类【JDK源码分析】
LinkedList类【JDK源码分析】
53 0