Java并发编程实战 第4章 对象的组合
Java监视器模式
java监视器模式就是在将共享的数据封装在一个类里面,然后然后所有访问或者修改这些数据的方法都标注为synchronize。
车辆追踪模拟:
使用监视器模式:
CarTracker对象维护了一个所有汽车坐标的Map,这个Map是竞争资源,线程会同时对它进行更新和读取。所以才每个方法上都加了synchronized。
- package com.zjf;
- import java.util.*;
- //定义坐标
- class Point{
- public int x,y;
- public Point(Point p){
- this.x=p.x;
- this.y=p.y;
- }
- }
- //车辆追踪
- public class CarTracker{
- //维护所有车辆的坐标Map key是汽车的ID 这是竞争资源
- private Map<String,Point> locations;
- public CarTracker(Map<String,Point> points){
- locations=deepCopy(points);
- }
- //获得所有车辆的坐标Map
- public synchronized Map<String,Point> getLocations(){
- return deepCopy(locations);
- }
- //所有某一车辆的坐标
- public synchronized Point getLocation(String id){
- Point p=locations.get(id);
- return (p==null)?null:new Point(p);
- }
- //设置某一个汽车的坐标
- public synchronized void setLocation(String id,int x,int y){
- Point p=locations.get(id);
- if(p==null)
- System.out.print("id not exists");
- p.x=x;
- p.y=y;
- }
- //深拷贝
- public static Map<String,Point> deepCopy(Map<String,Point> m){
- Map<String,Point> result=new HashMap<String,Point>();
- for(String id:m.keySet()){
- result.put(id,new Point(m.get(id)));
- }
- return Collections.unmodifiableMap(result);
- }
- }
使用java的并发集合来重写上面的代码:
- package com.zjf;
- import java.util.*;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentMap;
- //定义坐标 这个是不可变类型 所以可以直接返回 不担心被修改
- class Point {
- public final int x, y;
- public Point(int x, int y) {
- this.x = x;
- this.y = y;
- }
- }
- // 车辆追踪
- public class CarTracker {
- // 维护所有车辆的坐标Map key是汽车的ID 这是竞争资源 使用ConcurrentMap
- private final ConcurrentMap<String, Point> locations;
- //是locations的视图 locations的变化会直接映射到这里 但是它是不可修改的。
- private final Map<String, Point> unmodifiableMap;
- public CarTracker(Map<String,Point> points){
- locations =new ConcurrentHashMap<String,Point>(points);
- unmodifiableMap=Collections.unmodifiableMap(locations);
- }
- // 获得所有车辆的坐标Map 结果是不可修改的
- public Map<String,Point> getLocations(){
- return unmodifiableMap;
- }
- // 获取某一车辆的坐标 结果也是不可修改的
- public Point getLocation(String id){
- return locations.get(id);
- }
- // 设置某一个汽车的坐标 使用replace方法 这是ConcurrentMap提供的并发安全的方法
- public void setLocation(String id,int x,int y){
- if(locations.replace(id,new Point(x,y))==null)
- System.out.print("id not exists");
- }
- }
上面的方式,我们成为委托。我们把对车辆Map的并发管理委托给ConcurrentHashMap类。
Java并发编程实战 第4章 对象的组合的更多相关文章
- Java并发编程实战 第3章 对象的共享
可见性 可见性是由于java对于多线程处理的内存模型导致的.这似乎是一种失败的设计,但是JVM却能充分的利用多核处理器的强大性能,例如在缺乏同步的情况下,Java内存模型允许编译器对操作顺序进行重排序 ...
- 【JAVA并发编程实战】2、对象的组合
1. 设计线程安全的类 1.找出构成对象状态的所有变量 2.找出约束状态变量的不变性条件 3.建立对象状态的并发访问管理策略 package cn.xf.cp.ch04; /** * *功能:JAVA ...
- Java并发编程实战---第六章:任务执行
废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...
- Java并发编程实战 第16章 Java内存模型
什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...
- 【java并发编程实战】第一章笔记
1.线程安全的定义 当多个线程访问某个类时,不管允许环境采用何种调度方式或者这些线程如何交替执行,这个类都能表现出正确的行为 如果一个类既不包含任何域,也不包含任何对其他类中域的引用.则它一定是无状态 ...
- Java并发编程实战 第8章 线程池的使用
合理的控制线程池的大小: 下面内容来自网络.不过跟作者说的一致.不想自己敲了.留个记录. 要想合理的配置线程池的大小,首先得分析任务的特性,可以从以下几个角度分析: 任务的性质:CPU密集型任务.IO ...
- 读书笔记-----Java并发编程实战(二)对象的共享
public class NoVisibility{ private static boolean ready; private static int number; private static c ...
- JAVA并发编程实战---第三章:对象的共享(2)
线程封闭 如果仅仅在单线程内访问数据,就不需要同步,这种技术被称为线程封闭,它是实现线程安全性的最简单的方式之一.当某个对象封闭在一个线程中时,这种方法将自动实现线程安全性,即使被封闭的对象本生不是线 ...
- JAVA并发编程实战---第三章:对象的共享
在没有同步的情况下,编译器.处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整.在缺乏足够同步的多线程程序中,要对内存操作的执行顺序进行判断几乎无法得到正确的结果. 非原子的64位操作 当 ...
随机推荐
- python-静态方法和类方法及其使用场景
静态方法和类方法 静态方法 我们在类中定义的方法都是对象方法,也就是说这些方法都是发送给对象的消息.实际上,我们写在类中的方法并不需要都是对象方法,例如我们定义一个"三角形"类,通 ...
- dapper使用时性能优化
数据库中类型 Area 数据库类型 varchar dapper 来操作数据库,不能直接写 sql Area=@Area) //dapper 对C#中的字符串类型 默认是对应数据库nva ...
- 【BW系列】SAP BW on HANA 迁移问题
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[BW系列]SAP BW on HANA 迁移问 ...
- EINT DINT ERTM DRTM EALLOW EDIS ESTOP0的理解
本文参考以下资料整理 https://wenku.baidu.com/view/6b0d6906cf84b9d528ea7a66.html http://pangqicheng123.blog.163 ...
- 手写朴素贝叶斯(naive_bayes)分类算法
朴素贝叶斯假设各属性间相互独立,直接从已有样本中计算各种概率,以贝叶斯方程推导出预测样本的分类. 为了处理预测时样本的(类别,属性值)对未在训练样本出现,从而导致概率为0的情况,使用拉普拉斯修正(假设 ...
- [开发技巧]·pandas如何保存numpy元素
[开发技巧]·pandas如何保存numpy元素 1.问题描述 在开发的过程中遇到一个问题,就是需要把numpy作为pandas的一个元素进行保存,注意不是作为一列元素.但是实践的过程中却不顺利, ...
- centos7 中如何查看、打开、关闭防火墙。
首先是看centos7的防火墙的状态,查看的命令为: sudo systemctl status firewalld. 查看后,看到active(running)就意味着防火墙打开了, 如果想关闭防火 ...
- Redhat7 CentOS7安装阿里云的yum源
先说CentOS的 1.备份 [root@harry ~]# cd /etc/yum.repos.d/ [root@harry yum.repos.d]# mkdir repo_bak [root@b ...
- wget断点续传下载需要登录的网站上的大文件
1 举个例子 xcode 2 方法 wget --load-cookies=cookies.txt -c url -c是断点续传,如果网络断了,再运行该命令会接着最新的下载继续下载. --load- ...
- spring aop之父子容器
需求;项目对外提供接口,要求每个对外接口都要进行token认证. 解决办法:写一个token认证的工具类,在每个需要认证的接口方法开始的地方,调用工具类中的token认证方法. 问题:因为要满足指定条 ...