Java Concurrency -CopyOnWriteArrayList

Foreword

Today we learn together under java.util.concurrent concurrent bag CopyOnWriteArrayList tools. When there are multiple threads may simultaneously traverse, modify a public array time, because if you do not want to use synchronize key to lock the entire array to affect performance, consider using CopyOnWriteArrayList.

CopyOnWriteArrayList API

CopyOnWriteArrayList defined as follows:

public class CopyOnWriteArrayList<E>
extends Object
implements List<E>, RandomAccess, Cloneable, Serializable

It is also part of the Java collection framework is ArrayList thread safe variants, with different ArrayList in that: CopyOnWriteArrayList array for modifying operation (add, set, etc.) is based on an internal data copy is performed. In other words, there are other threads may be inserted or deleted even when operating in a traverse thread, we can "thread safety" have to traverse CopyOnWriteArrayList.

Example 1: Insert (delete) data at the same traverse

The principle CopyOnWriteArrayList, in a thread traversing time (Iterator create objects), interior creates a "snapshot" of the array, iterate based on the snapshot of an Iterator, this snapshot of the array does not change during traversal, will not throw out ConcurrentModificationException. If there are other threads in the process of traversing try to change the contents of the array, it will copy the new data changes, and back again to access the array of thread, see is change over the array.

  1. CopyOnWriteArrayList create an array of numbers;

    CopyOnWriteArrayList<Integer> numbers = new CopyOnWriteArrayList<>(new Integer[]{1, 3, 5, 78});

  2. Create an iterator iterator;

    Iterator<Integer> iterator = numbers.iterator();

  3. To increase the numbers (or delete, modify) an element;

    numbers.add(100);

  4. Use iterator through the array of elements found traversing the results Iterator objects created before;

    List<Integer> result = new LinkedList<>();
    iterator.forEachRemaining(result::add);
    assertThat(result).containsOnly(1, 3, 5, 78);

Complete examples are as follows:

package org.java.learn.concurrent.copyonwritearraylist;


import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import static org.assertj.core.api.Assertions.*;

/**
 * 作用:
 * User: duqi
 * Date: 2017/11/9
 * Time: 11:20
 */
public class CopyOnWriteArrayListExample {

    public static void main(String[] args) {
        CopyOnWriteArrayList<Integer> numbers = new CopyOnWriteArrayList<>(new Integer[]{1, 3, 5, 78});

        Iterator<Integer> iterator = numbers.iterator();
        numbers.add(100);
        List<Integer> result = new LinkedList<>();
        iterator.forEachRemaining(result::add);
        assertThat(result).containsOnly(1, 3, 5, 78);

        Iterator<Integer> iterator2 = numbers.iterator();
        numbers.remove(3);
        List<Integer> result2 = new LinkedList<>();
        iterator2.forEachRemaining(result2::add);
        assertThat(result2).containsOnly(1, 3, 5, 78, 100);
    }
}

Example 2: Delete does not support one side while traversing

Since the implementation mechanism CopyOnWriteArrayList -> is not an array to be modified and read operations to get the Iterator object points, thus deleting the results-based approach does not support Iterator objects: public void remove();Examples code is as follows:

package org.java.learn.concurrent.copyonwritearraylist;

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 作用: User: duqi Date: 2017/11/9 Time: 13:40
 */
public class CopyOnWriteArrayListExample2 {

    public static void main(String[] args) {
        try {
            testExceptionThrow();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void testExceptionThrow() {
        CopyOnWriteArrayList<Integer> numbers = new CopyOnWriteArrayList<>(new Integer[]{1, 3, 5, 78});
        Iterator<Integer> integerIterator = numbers.iterator();
        while (integerIterator.hasNext()) {
            integerIterator.remove();
        }
    }
}

in conclusion

CopyOnWriteArrayList suitable for use in a read operation is far greater than the write operation of the scene, such as caching. It is modified when doing copy, old and new versions of separation, to ensure high performance read for read-mostly the case.

Reference material

  1. Guide to CopyOnWriteArrayList
  2. Detailed CopyOnWriteArrayList
  3. The official document: CopyOnWriteArrayList

This focus on the number of back-end technology, JVM troubleshooting and optimization, Java interview questions, personal growth and self-management, and other topics, providing front-line developers work and growth experience for the reader, you can expect to gain something here.
Jwadu

Guess you like

Origin www.cnblogs.com/javaadu/p/11229161.html