Java多线程编程核心技术--第四章–对象的组合

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/danielzhou888/article/details/82874728

004.第四章–对象的组合

 

Java多线程编程核心技术代码记录 多线程 对象的组合

4.1 设计线程安全的类

001.p46-在设计线程安全类的过程中的三个基本要素?

4.1.2 依赖状态的操作

002.p46-实现某个等待先验条件为真时才执行的操作,可以通过什么方法?

003.p43-发布一个静态构造对象的最简单,最安全的方式是?为什么?

4.2 实例封闭

004.p49-写一个封闭+加锁实现一个类线程安全的DEMO?


@ThreadSafe
public class PersonSet {

    private final Set<Person> myset = new HashSet<Person>();

    public synchronized void addPerson(Person p) {
        myset.add(p);
    }

    public synchronized boolean containsPerson(Person p) {
        return myset.contains(p);
    }
}
 

004.p50-实例封闭是构建线程安全类的最简单方式。

005.p50-Java平台的类库中提供了包装器工厂方法(如:Collections.synchronizedList及其类似方法),使得非线程安全的类可以在多线 程环境中安全的使用。这些工厂方法通过“装饰器模式”的原理是?什么是装饰器模式,原理,demo?

4.2.1 Java监视器模式

006.p51-什么是Java的监视器模式?Demo?举例Java(如线程安全计数器Counter、Vector、Hashtable)


 Counter:
public class Counter {

    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;
}

Vector:
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    protected Object[] elementData;
    protected int elementCount;

    public synchronized void copyInto(Object[] anArray) {
        System.arraycopy(elementData, 0, anArray, 0, elementCount);
    }
}
 

007.p51-通过一个私有锁来保护状态?demo?

public class PrivateLock{

    private final Object mylock = new Object();

    @GuardedBy("myLock")
    Widget widget;

    void someMethod(){
        synchronized(mylock){
        .....访问修改widget状态
        }
    }
}

 

008.p52-基于监视器模式的车辆追踪器demo?此模式的适应场景,优缺点,举例说明?


@ThreadSafe
public class MonitorVehicleTracker {
    @GuardedBy("this")
    private final Map<String, MutablePoint> locations;

    public MonitorVehicleTracker(Map<String, MutablePoint> points) {
        locations = deepCopy(points);
    }

    public synchronized Map<String, MutablePoint> getLocations() {
        return deepCopy(locations);
    }

    public synchronized MutablePoint getLocation(String key) {
        MutablePoint point = locations.get(key);
        return point == null ? null : new MutablePoint(point);
    }

    public synchronized void setLocation(String id, int x, int y) {
        if (id == null) {
            return;
        }

        MutablePoint point = locations.get(id);

        if (point == null) {
            throw new IllegalArgumentException("No such ID: " + id);
        }

        point.setPoint(x, y);
    }

    private Map<String, MutablePoint> deepCopy(Map<String, MutablePoint> points) {

        if (points == null) {
            return Maps.newHashMap();
        }

        Map<String, MutablePoint> result = Maps.newHashMapWithExpectedSize(points.size());

        for (String key : points.keySet()) {
            result.put(key, new MutablePoint(points.get(key)));
        }

        return Collections.unmodifiableMap(result);
    }
}



@NotThreadSafe
public class MutablePoint {
    private int x, y;

    public MutablePoint(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public MutablePoint() {}

    public MutablePoint(MutablePoint point) {
        if (point == null) {
            throw new IllegalArgumentException("param is null");
        }

        int[] pointArray = point.getPointArray();
            x = pointArray[0];
            y = pointArray[1];
        }
    }

    public int[] getPointArray() {
        int[] ret = new int[2];
        ret[0] = x;
        ret[1] = y;
        return ret;
    }

    public void setPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }
}


 

适应场景:适合一致性的需求,获取一致的快照 
不适合实时获取每辆车的最新信息,因为需要频繁的刷新快照。

4.3 线程安全性的委托

009.p54-基于委托的车辆追踪器?DEMO?

交由ConcurrentHashMap处理


@Immutable
public class Point {
    public final int x,y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}



@ThreadSafe

public class DelegatingVehicleTracker {

    private final ConcurrentHashMap<String, Point> localtions;

    private final Map<String, Point> unmodifiableMap;

    public DelegatingVehicleTracker(Map<String, Point> points){
        locations = new ConcurrentHashMap<String, Point>(points);
        unmodifiableMap = Collections.unmodifiableMap(locations);
    }

    // 返回实时位置
    public Map<String, Point> getLocations() {
        return unmodifiableMap;
    }

    public Point getLocation(String id) {
        return locations.get(id);
    }

    // 返回静态拷贝数据,而非实时数据
    public Point getLocations_static(){
        return Collections.unmodifiableMap(new HashMap<String, Point>(locations));
    }

    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);
    }
}
 

010.什么是CopyOnWrite容器?说说CopyOnWriteArrayList的实现原理? CopyOnWrite的应用场景?CopyOnWrite的缺点?

传送门

4.3.2 独立的状态变量

011.p56-将线程安全性委托给多个状态变量——图形组件,允许客户程序注册监控鼠标和键盘等事件的监听器?DEMO?



 public class VisualComponent {

    private final List<KeyListener> keyListeners = new CopyOnWriteArrayList<KeyListener>();

    private final List<MonseListener> monseListeners = new CopyOnWriteArrayList<MonseListener>();

    public void addKeyListener(KeyListener listener) {
        keyListeners.add(listener);
    }

    public void addMonseListener(MonseListener monseListener){
        monseListeners.add(monseListener);
    }

    public void removeKeyListener(KeyListener keyListener) {
        keyListeners.remove(keyListener);
    }

    public void removeMonseListener(MonseListener monseListener) {
        monseListeners.remove(monseListener);
    }

}

012.p58-发布状态的车辆追踪器?DEMO?



 // 线程安全且可变的Point类
@ThreadSafe
public class SafePoint {

    @GuardedBy("this") private int x,y;

    public SafePoint(int x, int y) {
        this.x = x;
        this.y = y;
    }

    private SafePoint (int[] a) { this(a[0], a[1]); }

    private 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) {
        locations = new ConcurrentHashMap<String, SafePoint>(locations);
        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);
    }
}

4.4 在现有的安全线程中添加功能

013.p60-在现有的安全线程中添加功能有几种方法?(添加一个新的原子操作)DEMO?

  1. 修改原始类;(行不通,原因:客户代码并不知道在同步封装器工厂方法中返回的List对象的类型)
  2. 拓展类机制;(行不通,原因:客户代码并不知道在同步封装器工厂方法中返回的List对象的类型)
  3. 客户端加锁机制;(脆弱)
  4. 组合(Composition)。(推荐)


 // 通过组合实现“若没有则添加”
@ThreadSafe
public class ImprovedList<T> implements List<T> {

    private final List<T> list;

    public ImprovedList (List<T> list) {
        this.list = list;
    }

    public synchronized boolean putIfAbsent(T x) {
        boolean absent = !list.contains(x);
        if(absent)
            list.add(x);
        return !absent;
    }

    public synchronized void clear () { list.clear(); }
}

猜你喜欢

转载自blog.csdn.net/danielzhou888/article/details/82874728