本系列学习在.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并发编程-数据结构不可变性的更多相关文章

  1. 2019年BAT面试通关宝典:数据结构+JVM+并发编程+分布式...

    前言 金三银四俗称跳槽黄金季,很多同学都想趁着这段时间拿高薪,去更牛逼的公司工作,认识更多大牛,提升自己的职场竞争力. 那怎样才能通过BAT面试官的考核?怎样成为一名Offer收割机? 收割Offer ...

  2. [书籍翻译] 《JavaScript并发编程》第六章 实用的并发

    本文是我翻译<JavaScript Concurrency>书籍的第六章 实用的并发,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript ...

  3. java并发编程 --并发问题的根源及主要解决方法

    目录 并发问题的根源在哪 缓存导致的可见性 线程切换带来的原子性 编译器优化带来的有序性 主要解决办法 避免共享 Immutability(不变性) 管程及其他工具 并发问题的根源在哪 首先,我们要知 ...

  4. .NET并发编程-函数式编程

    本系列学习在.NET中的并发并行编程模式,实战技巧 函数式编程 和面向过程编程POP(procedure oriented Programming)面向对象编程OOP(object oriented ...

  5. 伪共享(false sharing),并发编程无声的性能杀手

    在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...

  6. 【Java并发编程实战】-----“J.U.C”:Exchanger

    前面介绍了三个同步辅助类:CyclicBarrier.Barrier.Phaser,这篇博客介绍最后一个:Exchanger.JDK API是这样介绍的:可以在对中对元素进行配对和交换的线程的同步点. ...

  7. 【转】Java并发编程注意事项

    保证线程安全的三种方法: 不要跨线程访问共享变量 使共享变量是final类型的 将共享变量的操作加上同步 一开始就将类设计成线程安全的, 比在后期重新修复它,更容易. 编写多线程程序, 首先保证它是正 ...

  8. Java并发编程:Timer和TimerTask(转载)

    Java并发编程:Timer和TimerTask(转载) 下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer ...

  9. Java并发编程:并发容器之ConcurrentHashMap(转载)

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...

随机推荐

  1. Spring学习03

    6.Bean的自动装配 6.1 自动装配说明 自动装配是使用spring满足bean依赖的一种方法 spring会在应用上下文中为某个bean寻找其依赖的bean. Spring中bean的三种装配机 ...

  2. 手机QQ空间自动点赞登录

    学以致用~使用 Appium 模拟人类操控手机行为 V2.0在手机上运行,目前实现以下功能: 1.小黑屋模式,一分钟内给好友发100条消息然后进了好友的小黑屋 2.定时发消息提醒对象多喝热水~ 3.对 ...

  3. gstack pstack strace

    gstack pstack strace 通过进程号 查看 进程的工作目录 Linux神器strace的使用方法及实践 - 知乎 https://zhuanlan.zhihu.com/p/180053 ...

  4. 极光推送的设备唯一性标识 RegistrationID

    极光推送的设备唯一性标识 RegistrationID 极光推送的设备唯一性标识 RegistrationID | 极光博客 https://blog.jiguang.cn/registrationi ...

  5. Jackson学习

    Jackson 是一个能够将java对象序列化为JSON字符串,也能够将JSON字符串反序列化为java对象的框架. 本文的所有内容都可以从 Java JSON Jackson Introductio ...

  6. xftp 提示无法显示远程文件夹

    在用xftp远程服务器,打开文件夹的时候一直提示"无法显示远程文件夹" 解决方案: 1.网上大多解决方案是文件->属性->选项->将使用被动模式选项去掉即可 2. ...

  7. Python学习【第7篇】:字符串拼接

    1.格式化字符有%s,%d,%f浮点数 %s代表格式化字符串,s是string意思 msg = 'my name is %s'%"xiaoxing"print(msg)运行结果:m ...

  8. LIS的优化

    二分优化 在求一个最长不上升自序列中,显然其结尾元素越小,越有利于接其他元素,对答案的贡献也就可能会更高 那么我们可以用low[i]去存长度为i的LIS结尾元素的最小值 因此我们只要维护low数组 对 ...

  9. SparkMLlib—协同过滤推荐算法,电影推荐系统,物品喜好推荐

    SparkMLlib-协同过滤推荐算法,电影推荐系统,物品喜好推荐 一.协同过滤 1.1 显示vs隐式反馈 1.2 实例介绍 1.2.1 数据说明 评分数据说明(ratings.data) 用户信息( ...

  10. 深入理解java虚拟机,GC参考手册

    深入理解java虚拟机 一.<深入理解Java虚拟机> 1.第2章 Java内存区域与内存溢出异常 2.第3章 垃圾收集器与内存分配策略 3.第4章 虚拟机性能监控与故障处理工具 4.第5 ...