//built in global set to locale specific value (here a comma)
decimalSeparator = ','
function FormatDot(value : real):
//save the current decimal character
temp = decimalSeparator
//set the global value to be
decimalSeparator = '.'
//format() uses decimalSeparator behind the scenes
result = format(value)
//Put the original value back
decimalSeparator = temp
private int myInt = 0;
public int AddOne()
{
int tmp = myInt;
tmp = tmp + 1;
myInt = tmp;
return tmp;
}
现在,线程 A 和线程 B 都希望执行 AddOne()。但是 A 首先开始并将 myInt (0)的值读入 tmp。现在,由于某种原因,调度程序决定暂停线程 A 并将执行推迟到线程 B。线程 B 现在也将 myInt(仍然是0)的值读入它自己的变量 tmp 中。线程 B 完成了整个方法,所以在最后 myInt = 1。一个回来了。现在轮到 A 线程了。线程 A 继续。并将1添加到 tmp (对于线程 A,tmp 为0)。然后在 myInt中保存这个值。myInt又是1。
public class DelegatingVehicleTracker {
private final ConcurrentMap<String, Point> locations;
private final Map<String, Point> unmodifiableMap;
public DelegatingVehicleTracker(Map<String, Point> points) {
this.locations = new ConcurrentHashMap<String, Point>(points);
this.unmodifiableMap = Collections.unmodifiableMap(locations);
}
public Map<String, Point> getLocations(){
return this.unmodifiableMap; // User cannot update point(x,y) as Point is immutable
}
public Point getLocation(String id) {
return locations.get(id);
}
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);
}
}
}
如果我们使用的是原始的 MutablePoint类而不是 Point,那么我们将通过让 getLocations发布对不是线程安全的可变状态的引用来破坏封装。注意,我们稍微改变了车辆跟踪器类的行为; 当监视器版本返回位置的快照时,委托版本返回车辆位置的一个不可修改但“实时”的视图。这意味着,如果线程 A 调用 getLocations,而线程 B 稍后修改了一些点的位置,那么这些更改将反映在返回给线程 A 的 Map 中。
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);
}
}
VisualComponent使用一个 CopyOnWriteArrayList来存储每个侦听器列表; 这是一个线程安全的 List 实现,特别适合于管理侦听器列表(参见5.2.3节)。每个 List 都是线程安全的,并且因为没有将一个 List 的状态与另一个 List 的状态耦合起来的约束,所以 VisualComponent可以将其线程安全责任委托给底层的 mouseListeners和 keyListeners对象。