.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 ...
随机推荐
- 飞机大战(1)--添加logo和加载动画
注:以下代码都是用scratch 3.0版本编写 素材链接: 链接:https://pan.baidu.com/s/1sXqeZVuFgVTYT0OtqxXilw 提取码:1126 一.背景添加 导入 ...
- ESPNet/ESPNetV2:空洞卷积金字塔 | 轻量级网络
ESPNet系列的核心在于空洞卷积金字塔,每层具有不同的dilation rate,在参数量不增加的情况下,能够融合多尺度特征,相对于深度可分离卷积,深度可分离空洞卷积金字塔性价比更高.另外,HFF的 ...
- (转载)微软数据挖掘算法:Microsoft Naive Bayes 算法(3)
介绍: Microsoft Naive Bayes 算法是一种基于贝叶斯定理的分类算法,可用于探索性和预测性建模. Naïve Bayes 名称中的 Naïve 一词派生自这样一个事实:该算法使用贝叶 ...
- maven project builder fails when running on jdk>9
java.lang.NoClassDefFoundError: Could not initialize class org.codehaus.plexus.archiver.jar.JarArchi ...
- fastjson的deserializer的主要优化算法 漏洞
JSON最佳实践 | kimmking's blog http://kimmking.github.io/2017/06/06/json-best-practice/ Fastjson内幕 Java综 ...
- .NET并发编程-函数式编程
本系列学习在.NET中的并发并行编程模式,实战技巧 函数式编程 和面向过程编程POP(procedure oriented Programming)面向对象编程OOP(object oriented ...
- ctsc选课
CTSC 1997 大学实行学分制.每门课程都有一定的学分,学生只要选修了这门课并通过考核就能获得相应学分.学生最后的学分是他选修各门课的学分总和. 每个学生都要选择规定数量的课程.有些课程可以直接选 ...
- yum安装docker-ce-18.03.0
yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo http://mir ...
- ThinkPHP 漏洞利用
ThinkPHP thinkphp_5x_命令执行漏洞 受影响版本包括5.0和5.1版本 docker漏洞环境源码: https://github.com/vulnspy/thinkphp-5.1.2 ...
- Geotools操作GeoJSON:解析FeatureCollection对象文件
Geotools操作GeoJSON:解析FeatureCollection对象文件 一.解析FeatureCollection对象文件 1.1 geotools操作GeoJSON过程中的问题及相关源码 ...