设计模式Copy-on-write
1.Copy-on-Write
又称COW,写时复制
String的replace()方法,没有修改内部的value数组,而是新创建了一个不可变对象
这种方法在解决不可变对象时,经常使用
这其实就是一种Copy-on-write方式
不可变对象的写操作往往都是使用 Copy-on-Write 方法解决的,当然 Copy-on-Write 的应用领域并不局限于 Immutability 模式
2.CopyOnWriteArrayList 和 CopyOnWriteArraySet
本质就是使用了COW思想
线程安全,试用于读多写少的场景,提升了性能的同时,也是通过COW复制出新的内存空间的代价换来的
读无锁,性能高。
修改的时候,会同事复制整个容器,以复制内存为代价,提升性能
3.linux的copy-on-write
fork子进程的时候,也是使用这种思路
父进程的地址空间现在用到了 1G 的内存,那么 fork() 子进程的时候要复制父进程整个进程的地址空间(占有 1G 内存)给子进程,这个过程是很耗时的。而 Linux 中的 fork() 函数就聪明得多了,fork() 子进程的时候,并不复制整个进程的地址空间,而是让父子进程共享同一个地址空间;只用在父进程或者子进程需要写入的时候才会复制地址空间,从而使父子进程拥有各自的地址空间。
在进程方面,因为子进程和父进程必须是不同的进程地址空间,数据也要隔离,所以copy-on-write其实只是一种延迟策略,在需要时复制,不需要时使用父进程的地址空间
4.微服务路由表应用案例
客户端调用远程服务,需要获取路由表,然后从路由表选则其中之一去调用
每次调用前,都需要获取路由表,服务的上下线状态不是很频繁,而且一段时间间隔非实时性也是可以容忍的,弱一致性
思考:
服务提供方,每次上线,下线,都会更新路由信息。
是否可以通过更新Router的一个状态位来表示,如果这样,那么客户端获取路由,访问该状态位的时候都需要同步访问(有可能获取状态的时候,状态正在被修改,假如被加锁,这时候就需要等待,等待写完了,再读),性能不好。如果采用Immutability不可变模式,每次上线,下线,都创建新的Router对象或者删除对应的Router对象,直接访问不受影响
代码范例
//路由信息
public final class Router{
private final String ip;
private final Integer port;
private final String iface;
//构造函数
public Router(String ip,
Integer port, String iface){
this.ip = ip;
this.port = port;
this.iface = iface;
}
//重写equals方法
public boolean equals(Object obj){
if (obj instanceof Router) {
Router r = (Router)obj;
return iface.equals(r.iface) &&
ip.equals(r.ip) &&
port.equals(r.port);
}
return false;
}
public int hashCode() {
//省略hashCode相关代码
}
}
//路由表信息
public class RouterTable {
//Key:接口名
//Value:路由集合
ConcurrentHashMap<String, CopyOnWriteArraySet<Router>>
rt = new ConcurrentHashMap<>();
//根据接口名获取路由表
public Set<Router> get(String iface){
return rt.get(iface);
}
//删除路由
public void remove(Router router) {
Set<Router> set=rt.get(router.iface);
if (set != null) {
set.remove(router);
}
}
//增加路由
public void add(Router router) {
Set<Router> set = rt.computeIfAbsent(
route.iface, r ->
new CopyOnWriteArraySet<>());
set.add(router);
}
}
设计模式Copy-on-write的更多相关文章
- HEC-ResSim原文档
HEC-ResSim Reservoir System Simulation User's Manual Version 3.1 May 201 ...
- PHP设计模式(六)原型模式(Prototype For PHP)
原型设计模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型设计模式简单的来说,顾名思义, 不去创建新的对象进而保留原型的一种设计模式. 缺点:原型设计模式是的最主要的缺点就 ...
- C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝
原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...
- C#设计模式
自从上次记录完“重构之道”以后,查询设计模式挺麻烦的.就打算把原先写的设计模式系列合并一下. 设计原则 使用设计模式的根本原因就是适应需求变化,提高代码的复用率,使程序更具有扩展性和可维护性. SOL ...
- 【iOS 单例设计模式】底层解析与运用
[iOS 单例设计模式]底层解析与运用 一.单例设计名词解释: (官方解释)单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例.(形象比喻)程序 — 公司 单例实例 - 管理 ...
- 小菜学习设计模式(四)—原型(Prototype)模式
前言 设计模式目录: 小菜学习设计模式(一)—模板方法(Template)模式 小菜学习设计模式(二)—单例(Singleton)模式 小菜学习设计模式(三)—工厂方法(Factory Method) ...
- Net设计模式实例之原型模式( Prototype Pattern)
一.原型模式简介(Brief Introduction) 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. Specify the kin ...
- 你真的了解iOS代理设计模式吗?
在项目中我们经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式来传递一些参数.这篇文章会涵盖代理的使用技巧和原理,以及代理的内存管理等方面的知识.我会通过这些方面的知识,带大 ...
- 设计模式之美:Iterator(迭代器)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Iterator 模式结构样式代码. 实现方式(二):实现 IEnumerable 中序遍历二叉树. 实现方式(三):实现 Bi ...
- 浅谈 MVVM 设计模式在 Unity3D 中的设计与实施
初识 MVVM 谈起 MVVM 设计模式,可能第一映像你会想到 WPF/Sliverlight,他们提供了的数据绑定(Data Binding),命令(Command)等功能,这让 MVVM 模式得到 ...
随机推荐
- 1075 PAT Judge
The ranklist of PAT is generated from the status list, which shows the scores of the submissions. Th ...
- c协程库libco几点体会
https://www.cnblogs.com/dearplain/p/9820913.html 这里说的是Tencent开源的libco. libco的用途和依赖 主要还是c/c++服务端,相比li ...
- 05- 移动端APP的分类 与对比webApp hybridApp nativeApp
随着智能手机的普及,移动端应用几乎成为每个互联网产品的标配.在快速迭代的互联网战场中高效开发.低成本上线产品,是每个应用开发团队追求的目标.此时,选择合适的应用类型和开发模式便至关重要.移动应用可以粗 ...
- Windows API初练手 -- 疯狂写文件代码
警告:恶作剧软件,慎用!仅供初学者研究代码所用!!! 提示:默认文件创建目录在"D:\test",如果需要使用的话请自行更改目录. 1. Windows API 版本 (调用系统函 ...
- UVA11292杀怪
题意: 一个怪物有N个头,每个头都有半径,然后有M个骑士,每个骑士能砍掉半径小于等于 X[i]的头,花费为X[i],并且一个骑士只能用一次,问砍掉怪物所有头的最小花费. 思路: ...
- Caddy-基于go的微型serve用来做反向代理和Gateway
1.简单配置 2.go实现,直接一个二进制包,没依赖. 3.默认全站https 常用 反向代理,封装多端口gateway 使用:启动直接执行二进制文件 caddy 就行 根据输出信息 直接https: ...
- javaScript的成长之路【何为函数,面向对象又是啥!!!】
- 使用jenkins一键打包发布vue项目
jenkins的安装 Jenkins是一款开源 CI&CD 软件,用于自动化各种任务,包括构建.测试和部署软件. Jenkins 支持各种运行方式,可通过系统包.Docker 或者通过一个独立 ...
- QQ可以登录,网页无法访问
之前以为是网络的问题,但是,后来发现QQ却可以登录,这是第二次碰到这个情况,所以总结一下 一般我们电脑上都会安装一个杀毒软件,比如火绒等等.我电脑上用的联想自带的电脑管家 我们可以在工具箱中找到网络诊 ...
- 一种用于 API 的查询语言-GraphQL
GitHub地址 官网地址 中文网址