CopyOnWrite容器解决的并发问题

CopyOnWrite容器解决的并发问题

    先看这么一段代码:
    public static void main(String[] args) throws InterruptedException {
        List<String> a = new ArrayList<String>();
        a.add("a");
        a.add("b");
        a.add("c");
        final ArrayList<String> list = new ArrayList<String>(
                a);
        Thread t = new Thread(new Runnable() {
            int count = -1;

            @Override
            public void run() {
                while (true) {
                    list.add(count++ + "");
                }
            }
        });
        t.setDaemon(true);
        t.start();
        Thread.currentThread().sleep(3);
        for (String s : list) {
            System.out.println(s);
        }
    }

    首先一个线程对ArrayList进行遍历操作,此间“休息”一段时间,另外一个线程进来,对List进行加入操作,此时“休息”后的线程继续对list遍历操作,运行爆出以下异常:


    这就是ArrayList在并发状态下发生错误,如何解决呢?引出今日猪脚--CopyOnWrite容器。

    一、源码

  1. put方法:
    public E set(int index, E element) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            E oldValue = get(elements, index);

            if (oldValue != element) {
                int len = elements.length;
                Object[] newElements = Arrays.copyOf(elements, len);
                newElements[index] = element;
                setArray(newElements);
            } else {
                // Not quite a no-op; ensures volatile write semantics
                setArray(elements);
            }
            return oldValue;
        } finally {
            lock.unlock();
        }
    }
    该方法对put操作上锁,并复制了原数组对象,对复制出来的数据进行修改操作,并在最后让原引用指向新对象,如此一来,就解决了并发问题。

猜你喜欢

转载自blog.csdn.net/that_is_cool/article/details/80598109