为什么并发很难?

几周前,我受邀在当地一所大学谈论并发。 本文总结了我在这里提出的内容。

我们都在大学期间或以其他方式了解并行性/并发性。 任何学习编程的人都将不可避免地阅读/学习一些基本概念,例如,

  • 线程,线程组,线程状态
  • 种族条件,互斥,死锁,饥饿
  • 锁,障碍,线程局部变量,原子变量
    这个清单继续...

尽管并发是主流,但我们仍然发现很难处理。 为什么?

一些观察:

  • 关于并发的入门资料与现实世界中的并发/分布式应用程序之间存在很大的差距。
  • 我们大多数人最终都没有遵循最佳实践。
  • 应用教科书,介绍性内容(或从Web上剪切粘贴)来解决该问题。

那么最终结果是什么?

  • 很多技术债务。
  • 应用程序性能/稳定性差。
  • 没有人理解代码! →很多不眠之夜/诅咒!

那么什么是解决方案?

由于过去的经验,我开始深入研究这个问题,显然我并不是唯一一个遭受痛苦的人。 互联网上有很多关于如何解决这个问题的文献。 这是一个摘要列表,谨记在心:

规则1:全局可变状态不好! (有或没有并发)

参考: https : //www.reddit.com/r/AskReddit/comments/90ogan/whats_the_least_ethical_thing_youve_done_in_your/
注意:如果状态随时间变化,则任何事物都是可变的 ,否则不变。
例如,全局静态变量,带有公共实例变量的静态类,单例对象,环境变量,配置对象,集群应用程序中共享的数据/状态量。

随着应用程序规模和复杂性的增长(考虑程序中的多个活动部件,并且程序在集群环境中运行),拥有大量全局可变状态使得无法在给定时间预测程序的下一个状态,尤其是当您处于故障排除模式。 为了使事情变得更糟,您将无法控制状态更改。

现在我不会成为理想主义者,而是说我们将拥有一个零全球状态! 因为这不切实际。 但是可以说我们需要将其保持在最低水平。

规则2:使用应用程序框架-遵循其编程模型。

我们编写的大多数代码(=〜90%?)都是关于移动数据的,例如[获取数据→做某事→在GUI中显示或放入存储中]。 这意味着我们无需处理,实际上不必直接处理并发。 除非我们正在编写一些特殊目的的代码,例如编写我们自己的框架/服务器运行时。

每种编程语言和周围的生态系统都提供更高级别的并发控制结构,因此我们大多数人不需要手动创建线程(同步块/锁等)。 这些范例中的大多数提供了基于组件的简单编程模型(例如,J2EE / Spring中的Bean,Servlet,控制器),使应用程序程序员可以将重点放在业务逻辑上而不是样板代码上。

因此,每次我们想引入线程/同步块时,退后一步并合理化需求总是一个好主意。

规则3-最佳做法

其中大多数只是显而易见的,并在更广泛的软件工程意义上应用。 我并不是要提供详尽的清单。 但是请发表评论,如果我错过了这里需要做的任何事情!

  • 减少对全局变量/数据的使用:使用正确的范围。 如果应用程序以该模式运行,则这需要在应用程序级别以及整个集群上发生。 这包括正确定义应用程序中的组件/层以及如何在每个相邻层之间交换数据/状态。
  • 最小化锁定范围 :不要滥用同步,我遇到了很多情况,在这种情况下,我们倾向于默认使用此方法来修复与并发相关的问题。 更多同步意味着性能降低的可能性更大。
  • 线程池:这是显而易见的。 创建线程需要大量的样板工作(以及运行时开销)。 如果有人愿意这样做,他/她将活在过去并试图重新发明轮子。
  • 使用更高层次的结构:我们中的一些人可能会不同意,但是我遇到的大多数数据共享需求都映射到消费者-生产者模式(及其变体)。 任何编程语言都应该通过并发包来支持。 为什么不使用它(例如,在Java中为java.util.concurrent.BlockingQueue的子类)。 还可以选择更复杂的替代方法,例如LMax Disruptor(Java中),Reactive编程(例如RxJava,Akka,Spring Reactor)。
  • 线程体系结构:并发不是我们以后要弄清楚/设计的一个方面。 考虑以下几点:
数据访问模式(例如,计算繁重/ IO繁重)
部署(例如VM环境,容器,工业计算机)硬件/资源约束
错误处理/跟踪/调试。

结论

  • 当我们缺乏“工作知识”并且没有遵循最佳实践时,处理并发就变得很困难。
  • 应用程序中过多的全局可变状态是有问题的。
  • 与使用裸机相比,更喜欢使用更高级别的并发控制构造(/框架)。
  • 预先选择/设计线程架构很重要。

滑轨:

https://www.slideshare.net/ramithj/concurrency-why-its-hard-126939361

参考文献:

From: https://hackernoon.com/why-concurrency-is-hard-a45295e96114

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值