創建線程安全對象的幾種方式

實例封閉

確保對象只能由單個線程訪問(線程封閉),或者通過一個鎖來保護對該對象的所有訪問,以確保對象是線程安全的。

實例代碼:

@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併發編程實戰》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章