zoukankan      html  css  js  c++  java
  • Java并发编程实战 第4章 对象的组合

    Java监视器模式

    java监视器模式就是在将共享的数据封装在一个类里面,然后然后所有访问或者修改这些数据的方法都标注为synchronize。

    车辆追踪模拟:

    使用监视器模式:

    CarTracker对象维护了一个所有汽车坐标的Map,这个Map是竞争资源,线程会同时对它进行更新和读取。所以才每个方法上都加了synchronized。

    1. package com.zjf;
    2.  
    3. import java.util.*;
    4.  
    5. //定义坐标
    6.  class Point{
    7.     public int x,y;
    8.     public Point(Point p){
    9.         this.x=p.x;
    10.         this.y=p.y;
    11.     }
    12. }
    13.  
    14. //车辆追踪
    15. public class CarTracker{
    16.    //维护所有车辆的坐标Map key是汽车的ID 这是竞争资源
    17.     private Map<String,Point> locations;
    18.     public CarTracker(Map<String,Point> points){
    19.         locations=deepCopy(points);
    20.     }
    21.     //获得所有车辆的坐标Map
    22.     public synchronized Map<String,Point> getLocations(){
    23.         return deepCopy(locations);
    24.     }
    25.     //所有某一车辆的坐标
    26.     public synchronized Point getLocation(String id){
    27.         Point p=locations.get(id);
    28.         return (p==null)?null:new Point(p);
    29.     }
    30.     //设置某一个汽车的坐标
    31.     public synchronized void setLocation(String id,int x,int y){
    32.         Point p=locations.get(id);
    33.         if(p==null)
    34.             System.out.print("id not exists");
    35.         p.x=x;
    36.         p.y=y;
    37.     }
    38.     //深拷贝
    39.     public static Map<String,Point> deepCopy(Map<String,Point> m){
    40.         Map<String,Point> result=new HashMap<String,Point>();
    41.         for(String id:m.keySet()){
    42.             result.put(id,new Point(m.get(id)));
    43.         }
    44.         return Collections.unmodifiableMap(result);
    45.     }
    46. }

    使用java的并发集合来重写上面的代码:

    1. package com.zjf;
    2.  
    3. import java.util.*;
    4. import java.util.concurrent.ConcurrentHashMap;
    5. import java.util.concurrent.ConcurrentMap;
    6.  
    7. //定义坐标 这个是不可变类型 所以可以直接返回 不担心被修改
    8. class Point {
    9.    public final int x, y;
    10.    public Point(int x, int y) {
    11.       this.x = x;
    12.       this.y = y;
    13.    }
    14. }
    15.  
    16. // 车辆追踪
    17. public class CarTracker {
    18.    // 维护所有车辆的坐标Map key是汽车的ID 这是竞争资源 使用ConcurrentMap
    19.    private final ConcurrentMap<String, Point> locations;
    20.    //是locations的视图 locations的变化会直接映射到这里 但是它是不可修改的。
    21.    private final Map<String, Point> unmodifiableMap;
    22.  
    23.    public CarTracker(Map<String,Point> points){
    24.         locations =new ConcurrentHashMap<String,Point>(points);
    25.         unmodifiableMap=Collections.unmodifiableMap(locations);
    26.     }
    27.  
    28.    // 获得所有车辆的坐标Map 结果是不可修改的
    29.    public Map<String,Point> getLocations(){
    30.         return unmodifiableMap;
    31.     }
    32.  
    33.    // 获取某一车辆的坐标 结果也是不可修改的
    34.    public Point getLocation(String id){
    35.         return locations.get(id);
    36.     }
    37.  
    38.    // 设置某一个汽车的坐标 使用replace方法 这是ConcurrentMap提供的并发安全的方法
    39.    public void setLocation(String id,int x,int y){
    40.         if(locations.replace(id,new Point(x,y))==null)
    41.             System.out.print("id not exists");
    42.     }
    43.  
    44. }

    上面的方式,我们成为委托。我们把对车辆Map的并发管理委托给ConcurrentHashMap类。

  • 相关阅读:
    phonegap helloworld 之android
    perl 信号
    css的浮动
    css的定位
    p4 环境变量的优先级
    oracle sql 高级
    perl数组高级
    让你提升命令行效率的 Bash 快捷键 [完整版]
    函数的返回值为结构体类型
    函数的返回值保存在内存的什么区域
  • 原文地址:https://www.cnblogs.com/xiaolang8762400/p/7056055.html
Copyright © 2011-2022 走看看