.NET并发编程-数据结构不可变性
本系列学习在.NET中的并发并行编程模式,实战技巧
内容目录
.NET不可变集合.NET并发集合函数式数据结构设计一个不可变类
作为程序员经常遇到产品上线后出现各种莫名其妙的问题,在我本地是好好的啊,也成为程序员面对未知问题的第一反应。这种不容易复现的问题,无非就是硬件不一致和软件不一致,更多的问题出在软件环境上,用户量、 并发这种测试容易遗漏的点。
为了保证编写的代码在不同的环境中出现一致的行为结果,通常就要利用不可变的数据结构。数据一旦创建后就不能修改其本身,修改后会产生新的数据。
.NET不可变集合
在.NET4.5引入不可变集合,在命名空间System.Collecttions.Immutable中。(注意这个类库不是.net核心类库,需要从nuget上安装)。不可变的集合结构每次修改数据后都会生成新的集合。像String类型一样,对它Substring,Replace都会生成新的字符串。
//可以将普通可变集合直接转为不可变集合
var dic = new Dictionary<int, int>().ToImmutableDictionary();
//直接创建不可变集合
var list = ImmutableList.Create<int>();
list = list.Add(1);
list = list.Add(2);
list = list.Add(3);
由于集合不可变,也就保证了多线程的安全。直接将集合丢给每个线程,原始集合不会变化。
.NET并发集合
还有一种线程安全集合在System.Collections.Concurrent中,在多线程环境中建议使用此类集合。Concurrent集合是可变集合,但提供了细粒度和无锁模式来提高多线程应用程序的性能和可扩展性。像ConcurrentDictionary字典,除了像传统字典Dictionary使用,还提供了很多兼容并发的方法,如AddOrUpdate或GetOrAdd等。如果不使用并发集合,在多线程环境中我们需要设置锁来保证数据的一致性。
函数式数据结构
可持久化数据结构也称之为函数式数据结构。可持久化意味着数据结构是不可变的,修改只会返回修改后的新数据结构。(这里数据持久化和IO持久化区分)。大多数命令式数据结构都是短暂的,修改就破坏其结构。如Dictionary,List,Queue等。
不可变性可能会带来一定的损耗,每次修改都会生成新的数据数据结构。但在托管编程语言中,如C# 和Java中,已经做了足够多的优化,且在多核时代,基本可以忽略性能的影响。
以链表数据结构为例说明托管语言在共享数据结构上做的优化
不可变的数据集合,每次修改后,不是完整拷贝原集合,比如集合中追加一项,只会修改引用指向的位置,共享剩余其他结构。
设计一个不可变类
C#有readonly和const两个关键字,还记得他们的区别和用处吗。const静态常量,编译时被解析,通过类访问。readonly动态常量,可延迟到构造函数中初始化,通过类实例访问。
public class Person
{
public const string Contry = "中国";
public string Name { get; }
public readonly Address Address;
public Person(string name, Address address)
{
this.Name = name;
this.Address = address;
}
}
public class Address
{
public string Street;
public Address(string street)
{
this.Street = street;
}
}
代码示例中,控制了Person的Address地址是不能被修改的,但它的底层字段Street仍然可以被修改。这就会导致person.Address.Street="M78星云"这样的行为,所以这就是浅不可变。微软考虑到不可变编程的重要性,随后又在C#6.0又引入了自动属性的概念,可以轻松的创建一个不可变类。像示例中的public string Name { get; }这样。
to be contiued!
下集:数据并行
.NET并发编程-数据结构不可变性的更多相关文章
- 2019年BAT面试通关宝典:数据结构+JVM+并发编程+分布式...
前言 金三银四俗称跳槽黄金季,很多同学都想趁着这段时间拿高薪,去更牛逼的公司工作,认识更多大牛,提升自己的职场竞争力. 那怎样才能通过BAT面试官的考核?怎样成为一名Offer收割机? 收割Offer ...
- [书籍翻译] 《JavaScript并发编程》第六章 实用的并发
本文是我翻译<JavaScript Concurrency>书籍的第六章 实用的并发,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript ...
- java并发编程 --并发问题的根源及主要解决方法
目录 并发问题的根源在哪 缓存导致的可见性 线程切换带来的原子性 编译器优化带来的有序性 主要解决办法 避免共享 Immutability(不变性) 管程及其他工具 并发问题的根源在哪 首先,我们要知 ...
- .NET并发编程-函数式编程
本系列学习在.NET中的并发并行编程模式,实战技巧 函数式编程 和面向过程编程POP(procedure oriented Programming)面向对象编程OOP(object oriented ...
- 伪共享(false sharing),并发编程无声的性能杀手
在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...
- 【Java并发编程实战】-----“J.U.C”:Exchanger
前面介绍了三个同步辅助类:CyclicBarrier.Barrier.Phaser,这篇博客介绍最后一个:Exchanger.JDK API是这样介绍的:可以在对中对元素进行配对和交换的线程的同步点. ...
- 【转】Java并发编程注意事项
保证线程安全的三种方法: 不要跨线程访问共享变量 使共享变量是final类型的 将共享变量的操作加上同步 一开始就将类设计成线程安全的, 比在后期重新修复它,更容易. 编写多线程程序, 首先保证它是正 ...
- Java并发编程:Timer和TimerTask(转载)
Java并发编程:Timer和TimerTask(转载) 下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer ...
- Java并发编程:并发容器之ConcurrentHashMap(转载)
Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...
随机推荐
- 面试常问的ArrayQueue底层实现
public class ArrayQueue<T> extends AbstractList<T>{ //定义必要的属性,容量.数组.头指针.尾指针 private int ...
- Kafka分区分配策略(Partition Assignment Strategy)
众所周知,Apache Kafka是基于生产者和消费者模型作为开源的分布式发布订阅消息系统(当然,目前Kafka定位于an open-source distributed event streamin ...
- e.next = nil // avoid memory leaks e.prev = nil // avoid memory leaks
/Go/src/container/list/list.go:10
- Boyer-Moore 投票算法
Boyer-Moore 投票算法 http://theory.stanford.edu/~trevisan/cs154-12/notestream.pdf 众数
- Dubbo 最基本的几个需求
需求 http://dubbo.apache.org/zh-cn/docs/user/preface/requirements.html 在大规模服务化之前,应用可能只是通过 RMI 或 Hessia ...
- nginx 配置文件解读
参考:链接 在微服务的体系之下,Nginx正在被越来越多的项目采用作为网关来使用,配合 Lua 做限流.熔断等控制 --源自 nginx Lua 脚本语言,用标准C语言编写并以源代码形式开放, 其设计 ...
- JTS Geometry
JTS Geometry关系判断和分析 JTS Geometry关系判断和分析 1.关系判断 1.1实例 2.关系分析 2.1实例 JTS(Geometry) JTS Geometry关系判断和分析 ...
- JYM虚拟机性能监控与故障处理工具
虚拟机性能监控与故障处理工具 一.jps:虚拟机进程状况工具 常用指令 二.jstat:虚拟机统计信息监视工具 常用指令 三.jinfo:配置信息工具 四.jmap:Java内存映像工具 常用指令 五 ...
- Java方式导出EXCEL表格
最近几天做公司项目,应客户需求需要将表单的数据下载本地存成.xls文件.之前做毕设的时候,就有类似这方面的功能需 求,但是当时也没有做就搁浅了下来,这次补上. 一.业务开发描述 二.前台jsp页面及j ...
- 9. Linux用户身份和能力
root 拥有最高的系统所有权,能够管理系统的各项功能,如添加/删除用户.启动/关闭服务进程.开启/禁用硬件设备等.以root 管理员的身份工作时不会受到系统的限制 在Linux 系统中,UID 有唯 ...