Java监视器模式

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

车辆追踪模拟:

使用监视器模式:

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

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

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

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

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

转载于:https://www.cnblogs.com/xiaolang8762400/p/7056055.html

Java并发编程实战 第4章 对象的组合相关推荐

  1. Java并发编程实战笔记2:对象的组合

    设计线程安全的类 在设计现车让安全类的过程之中,需要包含以下三步: 找出构成对象状态的所有变量 找出约束状态变量的不变性条件 建立对象状态的并发访问策略 实例封闭 通过封闭机制与合适的加锁策略结合起来 ...

  2. java并发编程实战-第三章-对象的共享

    3.1可见性 首先我们需要知道的是,java的线程都有自己独立的缓存,线程之间进行共享变量的交互是通过自身和缓存和主存的交互实现的. 如果线程的每次更改缓存都刷入主存,主存每次被一个线程的缓存修改,都 ...

  3. JAVA并发编程实战---第三章:对象的共享(2)

    线程封闭 如果仅仅在单线程内访问数据,就不需要同步,这种技术被称为线程封闭,它是实现线程安全性的最简单的方式之一.当某个对象封闭在一个线程中时,这种方法将自动实现线程安全性,即使被封闭的对象本生不是线 ...

  4. JAVA并发编程实战---第三章:对象的共享

    在没有同步的情况下,编译器.处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整.在缺乏足够同步的多线程程序中,要对内存操作的执行顺序进行判断几乎无法得到正确的结果. 非原子的64位操作 当 ...

  5. 【JAVA并发编程实战】1、对象的共享

    1.栈封闭 在栈封闭中,只能通过局部变量才能访问对象. 所谓栈封闭就是把变量的声明以及应用都局限在一个局部线程中,在这个局部线程中声明和实例化的对象对于线程外部是不可见的,这个局部线程的栈,无法被任何 ...

  6. Java并发编程实战 第14章 构建自定义的同步工具

    状态依赖性 定义:只有满足特定的状态才能继续执行某些操作(这些操作依赖于固定的状态,这些状态需要等待别的线程来满足). FutureTask,Semaphroe,BlockingQueue等,都是状态 ...

  7. Java并发编程实战 第13章 显式锁

    接口Lock的实现类: ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock Reentra ...

  8. java单线程共享,「Java并发编程实战」之对象的共享

    前言 本系列博客是对<Java并发编程实战>的一点总结,本篇主要讲解以下几个内容,内容会比较枯燥.可能大家看标题不能能直观的感受出到底什么意思,这就是专业术语,哈哈,解释下,术语(term ...

  9. JAVA并发编程实战——共享对象

    目录 思维导图 1. 可见性 1. 1 过期数据 1.2 锁和可见性 1.3 Volatile变量 2. 发布和逸出 2.1 安全构建实践 3. 线程封闭 3.1 栈限制 3.2 ThreadLoca ...

最新文章

  1. 创建模板_UG中如何创建属于自己的编程模板界面?
  2. 如果当初学习编程时能有人给我这些忠告该多好
  3. ZOJ 1610 Count the Colors 【线段树】
  4. H5 的getImageData造成的大量内存开销
  5. php常量数组吗,包含数组的PHP常量?
  6. CAP-微服务间通信实践
  7. 微信又更新了!支持上班摸鱼了
  8. haproxy Starting proxy XXX: cannot bind socket
  9. Java教程:Java程序的运行过程(执行流程)分析
  10. 力扣 26.删除有序数组中的重复元素
  11. Python的数学计算库scipy介绍
  12. 软件测试常见Bug清单
  13. leggedrobotics free gait 足式机器人自由步态 苏黎世机器人系统实验室
  14. 硬盘服务器哪个好用吗,服务器用固态硬盘好还是机械硬盘好
  15. word 任意页设置开始页码
  16. 简单3步打造明星气质妆容 清凉入夏
  17. 北京最新城市总体规划草案
  18. scala程序启动时,Could not locate executable null\bin\winutils.exe in the Hadoop binaries解决方案...
  19. 频域法分析系统详解及个人笔记
  20. android手机壁纸

热门文章

  1. awk -f 分隔符 命令_详解!!!awk参见使用命令
  2. HTTPS 传参数(Query String)安全吗?
  3. 【spring-session】介绍
  4. 【Zabbix】邮件接收 Problem 通知
  5. java akka_Akka系列(九):Akka分布式之Akka Remote
  6. 火车头采集php源码不同,防火车头采集的功能
  7. 菜鸟教程php多久学完,十天学会php(1)
  8. ubuntu16 自启动mysql_Ubuntu16.04关闭apache/mysql/php的开机启动
  9. php7连接oracle数据库,使用一个持久连接连到 Oracle 数据库 - PHP 7 中文文档
  10. httpclient 设置短连接_HTTP长连接、短连接使用及测试