forked from WegraLee/effective-java-3e-source-code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathObservableSet.java
More file actions
72 lines (61 loc) · 2.38 KB
/
Copy pathObservableSet.java
File metadata and controls
72 lines (61 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package effectivejava.chapter11.item79;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
// 관찰자 패턴을 구현하여, 원소가 추가되면 알려주는 집합 (420-425쪽)
public class ObservableSet<E> extends ForwardingSet<E> {
public ObservableSet(Set<E> set) { super(set); }
// 코드 79-1 잘못된 코드. 동기화 블록 안에서 외계인 메서드를 호출한다. (420쪽)
// private final List<SetObserver<E>> observers
// = new ArrayList<>();
// public void addObserver(SetObserver<E> observer) {
// synchronized(observers) {
// observers.add(observer);
// }
// }
//
// public boolean removeObserver(SetObserver<E> observer) {
// synchronized(observers) {
// return observers.remove(observer);
// }
// }
// private void notifyElementAdded(E element) {
// synchronized(observers) {
// for (SetObserver<E> observer : observers)
// observer.added(this, element);
// }
// }
// // 코드 79-3 외계인 메서드를 동기화 블록 바깥으로 옮겼다. - 열린 호출 (424쪽)
// private void notifyElementAdded(E element) {
// List<SetObserver<E>> snapshot = null;
// synchronized(observers) {
// snapshot = new ArrayList<>(observers);
// }
// for (SetObserver<E> observer : snapshot)
// observer.added(this, element);
// }
// 코드 79-4 CopyOnWriteArrayList를 사용해 구현한 스레드 안전하고 관찰 가능한 집합 (425쪽)
private final List<SetObserver<E>> observers =
new CopyOnWriteArrayList<>();
public void addObserver(SetObserver<E> observer) {
observers.add(observer);
}
public boolean removeObserver(SetObserver<E> observer) {
return observers.remove(observer);
}
private void notifyElementAdded(E element) {
for (SetObserver<E> observer : observers)
observer.added(this, element);
}
@Override public boolean add(E element) {
boolean added = super.add(element);
if (added)
notifyElementAdded(element);
return added;
}
@Override public boolean addAll(Collection<? extends E> c) {
boolean result = false;
for (E element : c)
result |= add(element); // notifyElementAdded를 호출한다.
return result;
}
}