openplanning

Hướng dẫn và ví dụ Java CopyOnWriteArraySet

  1. CopyOnWriteArraySet
  2. Examples

1. CopyOnWriteArraySet

CopyOnWriteArraySet là một lớp thi hành interface Set, thường được sử dụng trong một môi trường multithreading (đa luồng) và các hoạt động duyệt qua các phần tử được sử dụng nhiều hơn so với các hoạt động đột biến như add, remove, clear.
public class CopyOnWriteArraySet<E> extends AbstractSet<E> implements java.io.Serializable
CopyOnWriteArraySet quản lý một đối tượng CopyOnWriteArrayList bên trong nó. Tất cả các hoạt động add, remove, clear sẽ được thực hiện trên CopyOnWriteArrayList và đảm bảo rằng nó không chứa các phần tử trùng lặp.
CopyOnWriteArraySet là một Set an toàn theo luồng (thread-safe), sẽ dễ dàng hơn để hiểu về điều này nếu bạn dành chút thời gian đọc bài viết về CopyOnWriteArrayList dưới đây:
Mỗi khi bạn thực hiện một hoạt động gây đột biến như add, remove, clear sẽ tạo ra một mảng mới để lưu trữ các phần tử. Vì vậy chi phí để sử dụng CopyOnWriteArraySet là rất đắt đỏ, bạn phải trả giá nhiều hơn cho tài nguyên và hiệu suất. Tuy nhiên CopyOnWriteArraySet có ích khi bạn không thể hoặc không muốn đồng bộ hoá khi đi ngang qua (traverse) các phần tử của Set.
Khi bạn tạo ra đối tượng Iterator (hoặc Stream) từ CopyOnWriteArraySet, nó sẽ giúp bạn đi ngang qua các phần tử của mảng hiện thời (lúc Iterator hoặc Stream được tạo ra), các phần tử của mảng này sẽ không thay đổi trong suốt quá trình tồn tại của Iterator (hoặc Stream). Điều này có được vì bất cứ hoạt động add, remove, clear, .. nào trên CopyOnWriteArraySet sẽ tạo ra một mảng khác là bản sao của mảng hiện tại.
Đối tượng Iterator có được từ CopyOnWriteArraySet không hỗ trợ hoạt động Iterator.remove, nếu cố tình sử dụng bạn sẽ nhận được UnsupportedOperationException.

2. Examples

Ví dụ: Duyệt qua các phần tử của CopyOnWriteArraySet sử dụng Iterator, nó sẽ giúp bạn duyệt trên các phần tử của mảng hiện thời (Lúc Iterator đang được tạo ra).
CopyOnWriteArraySetEx1.java
package org.o7planning.copyonwritearrayset.ex;

import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

public class CopyOnWriteArraySetEx1 {

    public static void main(String[] args) {
        // Create a CopyOnWriteArraySet object:
        Set<String> set = new CopyOnWriteArraySet<String>();
        set.add("A");
        set.add("B");
        set.add("C");
        
        Iterator<String> iterator1 = set.iterator();
        
        set.add("X1");
        set.add("X2");
        
        Iterator<String> iterator2 = set.iterator();
        
        System.out.println("--- Iterator 1: -----");
        while(iterator1.hasNext()) {
            System.out.println(iterator1.next());
        }
        
        System.out.println("--- Iterator 2: -----");
        while(iterator2.hasNext()) {
            System.out.println(iterator2.next());
        }
    }
}
Output:
--- Iterator 1: -----
A
B
C
--- Iterator 2: -----
A
B
C
X1
X2
Chú ý: Iterator của CopyOnWriteArraySet không hỗ trợ hoạt động Iterator.remove.
Stream:
Di chuyển qua các phần tử của CopyOnWriteArraySet thông qua Stream cũng có kết quả giống với Iterator.
CopyOnWriteArraySetEx2.java
package org.o7planning.copyonwritearrayset.ex;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Stream;

public class CopyOnWriteArraySetEx2 {

    public static void main(String[] args) {
        // Create a CopyOnWriteArraySet object:
        Set<String> set = new CopyOnWriteArraySet<String>();
        set.add("A");
        set.add("B");
        set.add("C");  
        
        Stream<String> stream1 = set.stream();
        
        set.add("X1");
        set.add("X2");
        
        Stream<String> stream2 = set.stream();
        
        System.out.println("--- Stream 1: -----");
        stream1.forEach(System.out::println);
        
        System.out.println("--- Stream 2: -----");
        stream2.forEach(System.out::println);
    }
}
Output:
--- Stream 1: -----
A
B
C
--- Stream 2: -----
A
B
C
X1
X2
Ngoài các đặc điểm đặc biệt đã được đề cập ở trên CopyOnWriteArraySet cũng là một Set thông thường, bạn có thể tìm thấy các ví dụ khác về Set trong bài viết dưới đây:

Các hướng dẫn Java Collections Framework

Show More