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类。

最新文章

  1. 【ASP.NET】VS编译成功后自动生成Nuget包
  2. CSS的应用
  3. 2015年第13本(英文第9本):Murder on the Orient Express 东方快车谋杀案
  4. Oracle基础 exp/imp 数据泵导入/导出 命令
  5. 手把手教你WEB套打程序开发
  6. 打死也不换系统?笑谈过气的Windows XP
  7. 神经网络原理及其c++实现
  8. Krita编译和旧版本下载
  9. JS高程5.引用类型(6)Array类型的位置方法,迭代方法,归并方法
  10. 调用支付宝第三方接口(沙箱环境) SpringMVC+Maven
  11. 读取txt内文件内容
  12. gulp+ThinkPHP配置
  13. 【HDU 6171】Admiral(搜索+剪枝)
  14. 【二分+拓扑排序】Milking Order @USACO 2018 US Open Contest, Gold/upc_exam_6348
  15. 五校联考 running (欧拉函数)
  16. js中的offsetLeft和style.left
  17. asp.net core json返回的时间格式出现T 如何解决
  18. Rhino
  19. bzoj 1390: [Ceoi2008]Fence
  20. Git创建本地分支并关联远程分支

热门文章

  1. Dojo入门:dojo中的事件处理
  2. shadow使用方法
  3. mapreduce的shufflue过程
  4. ubuntu分区建议总结
  5. 模板if 的使用
  6. (5.1.4)引擎管理——SSMS管理使用小技巧
  7. Linux下面误删除文件使用extundelete工具恢复介绍
  8. Maven - Maven3实战学习笔记(1)Maven使用入门
  9. Hbase 三维存储
  10. springboot笔记-文件上传