Java CopyOnWriteArrayList introduction and code samples

features

CopyOnWriteArrayListis a thread-safe list implementation provided in the Java Concurrency Package. It achieves thread safety by creating a copy of the underlying array when the operation is modified, hence the name "Copy-On-Write".

Here are some of CopyOnWriteArrayListits features and detailed explanations:

  1. Thread Safety: CopyOnWriteArrayListIt is thread safe and can be accessed by multiple threads at the same time without additional synchronization measures. This is because its write operation is done by creating a copy of the underlying array, thus avoiding the problem of concurrent modification.

  2. Read operations are lock-free: read operations do not block other read operations, because each read operation is performed against an immutable copy. This CopyOnWriteArrayListleads to better performance in scenarios with more reads and fewer writes.

  3. Write operations copy the array: Whenever a write operation occurs (adding, modifying, or deleting an element), CopyOnWriteArrayLista copy of the underlying array is created and the modification operation is performed on the copy. This ensures that during the write operation, other threads can still safely read the original array.

  4. High memory usage: Since a copy array is created for each write operation, CopyOnWriteArrayListthe memory usage is high. Therefore, in scenarios with a large amount of data or frequent write operations, using CopyOnWriteArrayListmay result in excessive memory consumption.

  5. Applicable scenarios: CopyOnWriteArrayListApplicable to scenarios with more reads and fewer writes, such as data caches and event subscriptions where read operations far outnumber write operations. It provides an easy and thread-safe way to handle these scenarios.

code example

Here is a simple example showing how to use it CopyOnWriteArrayList:

import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteArrayListExample {
    
    
    public static void main(String[] args) {
    
    
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();

        // 添加元素
        list.add("Alice");
        list.add("Bob");
        list.add("Charlie");

        // 遍历元素
        for (String element : list) {
    
    
            System.out.println(element);
        }

        // 修改元素
        list.set(1, "David");

        // 删除元素
        list.remove(2);
    }
}

In the above example, we created an CopyOnWriteArrayListobject listand performed operations such as adding, traversing, modifying, and deleting. Since CopyOnWriteArrayListis thread-safe, we can perform these operations without additional synchronization measures.

It should be noted that CopyOnWriteArrayListthe write operation of is relatively slow because it involves copying the underlying array, so in scenarios where write operations are more frequent, performance may suffer. Therefore, it is very important to choose the appropriate data structure according to the actual situation.

About thread safety

Here is a simple sample code that demonstrates the thread safety CopyOnWriteArrayListof :

import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteArrayListExample {
    
    
    private static CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();

    public static void main(String[] args) {
    
    
        // 创建并启动多个线程
        Thread thread1 = new Thread(new AddElementTask());
        Thread thread2 = new Thread(new RemoveElementTask());
        thread1.start();
        thread2.start();

        // 等待线程执行完毕
        try {
    
    
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }

        // 打印最终的列表内容
        System.out.println("Final List:");
        for (String element : list) {
    
    
            System.out.println(element);
        }
    }

    static class AddElementTask implements Runnable {
    
    
        @Override
        public void run() {
    
    
            for (int i = 1; i <= 5; i++) {
    
    
                list.add("Element " + i);
                System.out.println("Added Element " + i);
                try {
    
    
                    Thread.sleep(100);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }

    static class RemoveElementTask implements Runnable {
    
    
        @Override
        public void run() {
    
    
            for (int i = 1; i <= 3; i++) {
    
    
                if (list.size() > 0) {
    
    
                    String removedElement = list.remove(0);
                    System.out.println("Removed " + removedElement);
                }
                try {
    
    
                    Thread.sleep(200);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

In the above example, we created a CopyOnWriteArrayListobject listand created two threads, one thread is used to add elements to the list and the other thread is used to remove elements from the list. Each thread sleeps for a period of time before performing operations.

Running the sample code, you can see that multiple threads modify concurrently CopyOnWriteArrayList, but there will be no thread safety issues. This is because the copy-on-write mechanism is used CopyOnWriteArrayListinternally , the underlying array is copied during the write operation, and the copied array is modified, thus ensuring thread safety.

It should be noted that although CopyOnWriteArrayListprovides thread safety, each write operation will create a copy of the underlying array, so in scenarios with frequent write operations, performance may be affected. Therefore, when choosing a data structure, it is necessary to weigh thread safety and performance according to actual needs.

Guess you like

Origin blog.csdn.net/a772304419/article/details/131024264