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 สูง