zoukankan      html  css  js  c++  java
  • CopyOnWrite容器之二:CopyOnWriteArraySet

    一、CopyOnWriteArraySet简介

    1. CopyOnWriteArraySet继承于AbstractSet,这就意味着它是一个集合。
    2. CopyOnWriteArraySet包含CopyOnWriteArrayList对象,它是通过CopyOnWriteArrayList实现的。而CopyOnWriteArrayList本质是个动态数组队列,
    所以CopyOnWriteArraySet相当于通过通过动态数组实现的“集合”! CopyOnWriteArrayList中允许有重复的元素;但是,CopyOnWriteArraySet是一个集合,所以它不能有重复集合。因此,CopyOnWriteArrayList额外提供了addIfAbsent()和addAllAbsent()这两个添加元素的API,通过这些API来添加元素时,只有当元素不存在时才执行添加操作!
    至于CopyOnWriteArraySet的“线程安全”机制,和CopyOnWriteArrayList一样,是通过volatile和互斥锁来实现的。这个在前一章节介绍CopyOnWriteArrayList时数据结构时,已经进行了说明,这里就不再重复叙述了。

    二、CopyOnWriteArraySet源码分析


    2.1、类图结构

    2.2、数据结构

    2.3、CopyOnWriteArraySet中的lock

    并发控制使用CopyOnWriteArrayList的ReentrantLock


    2.4、成员变量

    private final CopyOnWriteArrayList al;

    2.5、构造函数

        public CopyOnWriteArraySet()
        {
            al = new CopyOnWriteArrayList();
        }

    2.6、增加元素

        public boolean add(Object obj)
        {
            return al.addIfAbsent(obj);
        }

    2.7、remove

        public boolean remove(Object obj)
        {
            return al.remove(obj);
        }

    2.8、是否存在元素

        public boolean contains(Object obj)
        {
            return al.contains(obj);
        }

    2.9、size

        public int size()
        {
            return al.size();
        }

    2.10、clear

        public void clear()
        {
            al.clear();
        }

    三、JDK或开源框架中使用

    四、示例

    package com.dxz.concurrent.cow;
    
    import java.util.Iterator;
    import java.util.Set;
    import java.util.concurrent.CopyOnWriteArraySet;
    
    public class CopyOnWriteArraySetTest1 {
    
        // TODO: set是HashSet对象时,程序会出错。
        // private static Set<String> set = new HashSet<String>();
        private static Set<String> set = new CopyOnWriteArraySet<String>();
    
        public static void main(String[] args) {
    
            // 同时启动两个线程对set进行操作!
            new MyThread("ta").start();
            new MyThread("tb").start();
        }
    
        private static void printAll() {
            String value = null;
            Iterator iter = set.iterator();
            while (iter.hasNext()) {
                value = (String) iter.next();
                System.out.print(value + ", ");
            }
            System.out.println();
        }
    
        private static class MyThread extends Thread {
            MyThread(String name) {
                super(name);
            }
    
            @Override
            public void run() {
                int i = 0;
                while (i++ < 10) {
                    // “线程名” + "-" + "序号"
                    String val = Thread.currentThread().getName() + "-" + (i % 6);
                    set.add(val);
                    // 通过“Iterator”遍历set。
                    printAll();
                }
            }
        }
    }

    结果:

    ta-1, tb-1, 
    ta-1, tb-1, 
    ta-1, tb-1, ta-1, tb-1, ta-2, 
    ta-1, tb-1, ta-2, ta-2, tb-2, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, tb-0, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, tb-0, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, tb-0, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, tb-0, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-2, ta-3, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, tb-0, ta-4, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, tb-0, ta-4, ta-5, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-3, tb-4, tb-5, tb-0, 
    tb-4, tb-5, tb-0, ta-4, ta-5, ta-0, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, tb-0, ta-4, ta-5, ta-0, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, tb-0, ta-4, ta-5, ta-0, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, tb-0, ta-4, ta-5, ta-0, 
    ta-1, tb-1, ta-2, tb-2, ta-3, tb-3, tb-4, tb-5, tb-0, ta-4, ta-5, ta-0, 
  • 相关阅读:
    查看.Net Framework版本的方法
    JS手机号码自动换位
    VS2008正版序列号
    ASP.NET对XML的操作
    JS宽高度
    下载某个网站的内容
    C#中如何将控件中表格数据导出到exeal文档中
    像素 厘米 英寸 换算
    编程经验点滴避免使用汉语拼音做变量名
    编程经验点滴避免在数据库访问函数中使用 try catch
  • 原文地址:https://www.cnblogs.com/duanxz/p/2718424.html
Copyright © 2011-2022 走看看