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

004.第四章–对象的组合

 

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

  • 004.第四章–对象的组合
      • 4.1 设计线程安全的类
        • 001.p46-在设计线程安全类的过程中的三个基本要素?
        • 4.1.2 依赖状态的操作
          • 002.p46-实现某个等待先验条件为真时才执行的操作,可以通过什么方法?
          • 003.p43-发布一个静态构造对象的最简单,最安全的方式是?为什么?
      • 4.2 实例封闭
        • 004.p49-写一个封闭+加锁实现一个类线程安全的DEMO?
        • 004.p50-实例封闭是构建线程安全类的最简单方式。
        • 005.p50-Java平台的类库中提供了包装器工厂方法(如:Collections.synchronizedList及其类似方法),使得非线程安全的类可以在多线 程环境中安全的使用。这些工厂方法通过“装饰器模式”的原理是?什么是装饰器模式,原理,demo?
        • 4.2.1 Java监视器模式
          • 006.p51-什么是Java的监视器模式?Demo?举例Java(如线程安全计数器Counter、Vector、Hashtable)
          • 007.p51-通过一个私有锁来保护状态?demo?
          • 008.p52-基于监视器模式的车辆追踪器demo?此模式的适应场景,优缺点,举例说明?
      • 4.3 线程安全性的委托
        • 009.p54-基于委托的车辆追踪器?DEMO?
        • 010.什么是CopyOnWrite容器?说说CopyOnWriteArrayList的实现原理? CopyOnWrite的应用场景?CopyOnWrite的缺点?
        • 4.3.2 独立的状态变量
          • 011.p56-将线程安全性委托给多个状态变量——图形组件,允许客户程序注册监控鼠标和键盘等事件的监听器?DEMO?
          • 012.p58-发布状态的车辆追踪器?DEMO?
      • 4.4 在现有的安全线程中添加功能
        • 013.p60-在现有的安全线程中添加功能有几种方法?(添加一个新的原子操作)DEMO?

 

4.1 设计线程安全的类

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

4.1.2 依赖状态的操作

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

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

4.2 实例封闭

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


@ThreadSafe
public class PersonSet {

    private final Set myset = new HashSet();

    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 extends AbstractList implements List, 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 locations;

    public MonitorVehicleTracker(Map points) {
        locations = deepCopy(points);
    }

    public synchronized Map 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 deepCopy(Map points) {

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

        Map 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 localtions;

    private final Map unmodifiableMap;

    public DelegatingVehicleTracker(Map points){
        locations = new ConcurrentHashMap(points);
        unmodifiableMap = Collections.unmodifiableMap(locations);
    }

    // 返回实时位置
    public Map getLocations() {
        return unmodifiableMap;
    }

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

    // 返回静态拷贝数据,而非实时数据
    public Point getLocations_static(){
        return Collections.unmodifiableMap(new HashMap(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 keyListeners = new CopyOnWriteArrayList();

    private final List monseListeners = new CopyOnWriteArrayList();

    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 locations;
    private final Map unModifiableMap;

    public PublishingVehicleTracker (Map locations) {
        locations = new ConcurrentHashMap(locations);
        unModifiableMap = Collections.unModifiableMap(this.locations);
    }

    public Map 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 implements List {

    private final List list;

    public ImprovedList (List 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(); }
}

 

欢迎加入Java猿社区
 

你可能感兴趣的:(多线程)