นากกายถ่ายสำเนาแผ่นรายการแล้วอ่านสำเนา ขณะอีกฝั่งแก้ต้นฉบับ

CopyOnWriteArrayList: อ่าน snapshot ปลอดภัยตอน listener เยอะ

น้องกายEngineering

ระบบที่มี listener / subscriber อ่านตลอด แต่เพิ่ม-ลบคนฟังนาน ๆ ที ผมเลือก CopyOnWriteArrayList ครับ

ตามAPI การเขียนจะคัดลอกอาร์เรย์ใหม่ iterator ได้ snapshot ที่ไม่โยน ConcurrentModificationException แต่ Iterator.remove ใช้ไม่ได้

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

public class Main {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> listeners = new CopyOnWriteArrayList<>();
        listeners.add("a");
        listeners.add("b");
        Iterator<String> it = listeners.iterator();
        listeners.add("c");
        int seen = 0;
        while (it.hasNext()) {
            it.next();
            seen++;
        }
        assert seen == 2;
        assert listeners.size() == 3;
        System.out.println("CopyOnWriteArrayList tests passed");
    }
}

อย่าใช้กับลิสต์ที่เขียนถี่ — ค่าคัดลอกแพง เลือกเมื่ออัตราส่วนอ่าน >> เขียน

Recap

  • ใช้ตอน listener/read-mostly
  • จำว่า iterator เป็น snapshot
  • อ่านเอกสาร CopyOnWriteArrayList
  • หลีกเลี่ยงถ้ามี write สูง