// 使用Java监视器模式的线程安全计数器
@ThreadSafe
public final class Counter {
@GuardedBy("this") private long value = 0;
public synchronized long getValue () {
return value;
}
public synchronized long increment () {
if (value == Long.MAX_VALUE) {
throw new IllegalStateException("counter overflow");
}
return ++value;
}
}
// 基于监视器模式的车辆追踪
@ThreadSafe
public class MonitorVehicleTracker {
@GuardedBy("this")
private final Map<String, MutablePoint> locations;
public MonitorVehicleTracker (Map<String, MutablePoint> locations) {
this.locations = deepCopy(locations);
}
public synchronized Map<String, MutablePoint> getLocations () {
return deepCopy(locations);
}
public synchronized MutablePoint getLocation (String id) {
MutablePoint loc = locations.get(id);
return loc == null ? null : new MutablePoint(loc);
}
public synchronized void setLocation (String id, int x, int y) {
MutablePoint loc = locations.get(id);
if (loc == null) {
throw new IllegalArgumentException("No such ID:" + id);
}
loc.x = x;
loc.y = y;
}
private static Map<String, MutablePoint> deepCopy (Map<String, MutablePoint> m) {
Map<String, MutablePoint> result = new HashMap<String, MutablePoint>();
for (String id : m.ketSet()) {
result.put(id, new MutablePoint(m.get(id)));
}
return Collections.unmodifiableMap(result);
}
}
// 与Java.awt.Point类似的可变Point类
@NotThreadSafe
public class MutablePoint {
public int x, y;
public MutablePoint () {
x = 0;
y = 0;
}
public MutablePoint (MutablePoint p) {
this.x = p.x;
this.y = p.y;
}
}
线程安全性委托
示例:基于委托的车辆追踪器
// 在 DelegatingVehicleTrcker 中使用的不可变Point类
@Immutable
public class Point {
public final int x, y;
public Point (int x, int y) {
this.x = x;
this.y = y;
}
}
// 将线程安全性委托给多个状态变量
public class VisualComponent {
private final List<KeyListener> keyListeners
= new CopyOnWriteArrayList<KeyListener>();
private final List<MouseListener> mouseListeners
= new CopyOnWriteArrayList<MouseListener>();
public void addKeyListener (KeyListener listener) {
keyListeners.add(listener);
}
public void addMouseListener (MouseListener listener) {
mouseListeners.add(listener);
}
public void removeKeyListener (KeyListener listener) {
keyListeners.remove(listener);
}
public void removeMouseListener (MouseListener listener) {
mouseListeners.remove(listener);
}
}
当委托失效时
// NumberRange 类并不足以保护它的不变性条件
public class NumberRange {
// 不变性条件:lower <= upper
private final AtomicInteger lower = new AtomicInteger(0);
private final AtomicInteger upper = new AtomicInteger(0);
public void setLower (int i) {
// 注意 --- 不安全的“先检查后执行”
if (i > upper.get()) {
if (i > upper.get()) {
throw new IllegalArgumentException("can't set lower to " + i + " > upper");
}
lower.set(i);
}
}
public void setUpper (int i) {
// 注意 --- 不安全的“先检查后执行”
if (i < lower.get()) {
throw new IllegalArgumentException("can't set upper to " + i + " < lower");
}
upper.set(i);
}
public boolean isInRange (int i) {
return(i >= lower.get() && i <= upper.get());
}
}
// 线程安全且可变的Point类
@ThreadSafe
public class SafePoint {
@GuardedBy("this") private int x, y;
private SafePoint (int[] a) { this(a[0], a[1]); }
public SafePoint (SafePoint p) { this(p.get()); }
public synchronized int[] get () {
return new int[] { x, y };
}
public synchronized void set (int x, int y) {
this.x = x;
this.y = y;
}
}
// 安全发布底层状态的车辆追踪器
@ThreadSafe
public class PublishingVehicleTracker {
private final Map<String, SafePoint> locations;
private final Map<String, SafePoint> unmodifiableMap;
public PublishingVehicleTracker (Map<String, SafePoint> locations) {
this.locations
= new ConcurrentHashMap<String, SafePoint>(locations);
this.unmodifiableMap
= Collections.unmodifiableMap(this.locations);
}
public Map<String, SafePoint> getLocations () {
return unmodifiableMap;
}
public SafePoint getLocation (String id) {
return locations.get(id);
}
public void setLocation (String id, int x, int y) {
if (!locations.containsKey(id)) {
throw new IllegalArgumentException("invalid vehicle name:" + id);
}
locations.get(id).set(x, y);
}
}
在现有的线程安全类中添加功能
// 扩展Vector并增加一个“若没有则添加”方法
@ThreadSafe
public class BetterVector<E> extends Vector<E> {
public synchrnized boolean putIfAbsent (E x) {
boolean absent = !contains(x);
if (absent) {
add(x)
}
return absent;
}
}
// 非线程安全的“若没有则添加”
@NotThreadSafe
public class ListHelper<E> {
public List<E> list =
Collections.synchronizedList(new ArrayList<E>());
public synchronized boolean putIfAbsent (E x) {
boolean absent = !list.contains(x);
if (absent) {
list.add(x);
}
return absent;
}
}