實例封閉
確保對象只能由單個線程訪問(線程封閉),或者通過一個鎖來保護對該對象的所有訪問,以確保對象是線程安全的。
實例代碼:
@ThreadSafe
public class PersonSet {
@GuardedBy("this")
private final Set<User> mySet = new HashSet<>();
public synchronized void addUser(User user) {
mySet.add(user);
}
public synchronized boolean containsUser(User user) {
return mySet.contains(user);
}
}
及通過“裝飾器”封裝容器類實現線程安全:
List list = Collections.synchronizedList(new ArrayList());
Map map = Collections.synchronizedMap(new HashMap());
線程安全性的委託
在某些情況下,通過多個線程安全類組合而成的類是線程安全的。
實例代碼:
@ThreadSafe
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 unmodifiableMap;
}
public Point getLocation(String id) {
return locations.get(id);
}
public void setLocation(String id, Point point) {
if(locations.replace(id, point) == null) {
throw new IllegalArgumentException("invalid vehicle name: " + id);
}
}
}
@ThreadSafe
public class VisualComponent {
private final List<KeyListener> keyListeners = new CopyOnWriteArrayList<>();
private final List<MouseListener> mouseListeners = new CopyOnWriteArrayList<>();
public void addKeyListener(KeyListener keyListener) {
keyListeners.add(keyListener);
}
public void removeKeyListener(KeyListener keyListener) {
keyListeners.remove(keyListener);
}
public void addMouseListener(MouseListener mouseListener) {
mouseListeners.add(mouseListener);
}
public void removeMouseListener(MouseListener mouseListener) {
mouseListeners.remove(mouseListener);
}
}
現有的線程安全類中添加功能
重用現有的類可以降低開發工作量、開發風險
實例代碼:
/**
* 擴展Vector
*
**/
@ThreadSafe
public class BetterVector<E> extends Vector<E> {
public synchronized boolean putIfAbsent(E e) {
boolean absent = contains(e);
if (!absent) {
add(e);
}
return absent;
}
}
@ThreadSafe
public class ListHelper<E> {
public List<E> list = Collections.synchronizedList(new ArrayList<E>());
public boolean putIfAbsent(E e) {
//客戶端加鎖
synchronized (list) {
boolean absent = list.contains(e);
if (!absent)
list.add(e);
return absent;
}
}
}
參考:《Java併發編程實戰》