/**
* 私有锁示例
*/
public class PrivateLock {
private final Object myLock = new Object();
Widget widget;
void someMethod() {
synchronized(myLock) {
//访问或修改Widget的状态
}
}
}
Java线程监视器模式示例
/**
* Created by weicm on 2017/8/9.
* 可变位置,线程不安全
*/
public class MutablePoint {
public int x, y;
public MutablePoint() {
x = 0;
y = 0;
}
/**
* 位置对象拷贝
* @param p
*/
public MutablePoint(MutablePoint p) {
this.x = p.x;
this.y = p.y;
}
}
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Created by weicm on 2017/8/9.
* 基于Java监视器的线程安全的车辆追踪器
*
* 介绍:
* 线程安全实现方式:这种实现方式是通过在返回给客户端代码之前复制可变数据来维持线程安全性
* 缺点:如果车辆容器太大,getLocations会由与deepCopy会导致低性能
* 实现方式的好坏:如果结果需要保持一致性,那么这种方式很适合,如果结果要保持实时性,那么这种方式不符合要求
*/
public class MonitorVehicleTracker {
//追踪器状态
private final Map<String, MutablePoint> locations;
/**
* 通过深度拷贝传入的追踪器信息,初始化追踪器状态,避免追踪器状态逸出
* @param locations
*/
public MonitorVehicleTracker(Map<String, MutablePoint> locations) {
this.locations = deepCopy(locations);
}
/**
* 返回只读追踪器镜像,避免追踪器状态逸出
* @return
*/
public synchronized Map<String, MutablePoint> getLocations() {
return deepCopy(locations);
}
/**
* 获取位置镜像,避免位置状态对象逸出
* @param id
* @return
*/
public synchronized MutablePoint getLocation(String id) {
MutablePoint loc = locations.get(id);
return loc == null ? null : new MutablePoint(loc);
}
/**
* 通过深度拷贝追踪器创建器镜像,返回只读镜像
* @param m
* @return
*/
private static Map<String, MutablePoint> deepCopy(Map<String, MutablePoint> m) {
HashMap<String, MutablePoint> result = new HashMap<>();
for (String id: m.keySet())
result.put(id, new MutablePoint(m.get(id)));
return Collections.unmodifiableMap(result);
}
}
线程安全性委托示例
/**
* Created by weicm on 2017/8/10.
* 不可变位置,线程安全
*/
public class Point {
public final int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by weicm on 2017/8/10.
* 基于安全委托的线程安全的车辆追踪器
*/
public class DelegatingVehicleTracker {
//追踪器状态
private final ConcurrentHashMap<String, Point> locations;
//追踪器 实时 只读 对象(并不是状态对象,只做为应答结果,由与是只读的,所以安全)
private final Map<String, Point> unmodifiableMap;
/**
* 初始化,将状态对象委托给线程安全的类
* 同时,构造实时只读状态对象
* @param locations
*/
public DelegatingVehicleTracker(Map<String, Point> locations) {
this.locations = new ConcurrentHashMap<>(locations);
this.unmodifiableMap = Collections.unmodifiableMap(locations);
}
/**
* 返回实时只读状态对象,安全
* @return
*/
public Map<String, Point> getLocations() {
return unmodifiableMap;
}
/**
* 通过委托的线程安全对象,获取不可变位置状态,安全
* @param id
* @return
*/
public Point getLocation(String id) {
return locations.get(id);
}
/**
* 通过委托的线程安全对象,设置新的不可变位置状态,安全
* @param id
* @param x
* @param y
*/
public void setLocation(String id, int x, int y) {
if (locations.replace(id, new Point(x, y)) == null) {
throw new IllegalArgumentException("invalid vehicle name: " + id);
}
}
}
import java.util.concurrent.atomic.AtomicInteger;
/**
* 尽管NumberRange类状态变量委托给了线程安全的两个AtomicInteger类
* 但是由于存在复合操作,并不足以保护它的不变性条件
*/
public static 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()) {
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 isRange(int i) {
//注意:不安全的“复合操作”
return (i >= lower.get() && i <= upper.get());
}
}