当咱们在说“并发、多线程”,说的是什么?

这篇文章的目的并非想教你如何造火箭(面试造火箭,工做拧螺丝),而是想经过对原理和应用案例的有限度剖析来协助你构建起并发的思惟,并将操做系统的理论知识与工程实践结合起来,贯穿从学到会的全过程。固然,虽然咱们是从实用角度出发,但具备实践意义的深层次知识点永远会是面试中的杀手锏,这可比只能口头造火箭的理论知识更吸引面试官。面试

本文适合谁:数据库

  1. 但愿能了解并发概念的初学者
  2. 须要理清并发概念与技术的工程师
  3. 对并发在工做中的应用与其底层实现原理感兴趣的读者

在这篇文章中,你将了解到并发与多线程相关的一系列概念,经过一些例子咱们能够在不纠结于具体的技术细节的状况下造成对并发与多线程相关的各类概念的抽象理解。有了这些概念之后,咱们再去学习具体的理论和技术细节就是手到擒来的事了。编程

什么是并发?

最近几年淘宝发展得如火如荼,涌现出了一大批白手起家的卖家。想象一下你是一个刚刚起步的小卖家,本身运营一个服装网店,天天都要本身打包发货。刚开始时生意通常,天天本身一我的一个小时就能干完。网络

随着生意的蓬勃发展,发货时间慢慢地从一个小时涨到了两个小时、四个小时,一次由于延迟发货致使被投诉以后,你终于以为该招更多的人了。很快,两个小伙伴加入了你的事业,打包速度开始有了质的提升。这就是最基本的并发了,每一个人均可以当作是一个线程,一样的工做量,干得人多了天然就快了。多线程

因此并发就是经过多个执行器同时执行一个大任务来缩短执行时间、提升执行效率的方法。并发

数据竞争

可是好景不长,周末一盘货,你发现少了很多。这办公室里也没遭贼,怎么就会少货呢?细细一查快递单,你发现居然有几单发重了。以后的几天你都细细留意了一下发货的过程,最后发现是由于每一个人都会拿着一张发货清单去备货,若是有一些订单不当心打印重复了,就有可能会被不一样的人重复发货。虽然数量很少,可是也很心痛啊。这个问题产生的缘由就是由于每一个人在备货以前拿到的订单状态(未发货)在实际备货时发生了变化(已由其余人发货)。这种对一个共享数据(订单的发货状态)本应独占的读取、检查、修改过程,若是发生了并发,这种状况就被称为数据竞争。而这个读取、检查、修改的过程就被称为临界区临界区指的就是一个存在数据竞争的代码片断。分布式

数据竞争出现的根本缘由是一个数据原本应该只能由一个执行器完整地执行读取、检查、修改过程,可是若是出现了并发,那么就没办法保证到了“修改”这一步时的数据还保持了“读取”时的值了。工具

肯定缘由后,有人想到了一个好办法,能够打印一张总的发货清单,这样全部人都必须以这个清单上的订单是否发货来肯定是否要对订单进行备货并发货了。由于清单只有一份,因此每次只能由一我的来修改订单的发货状态。这种只能由一个执行器进行数据修改操做来避免发生数据竞争问题的作法就被称为互斥,也就是咱们常说的了。oop

分布式并发概念

分布式

由于你管理得当,生意发展得很快,如今的办公室里已经堆不下全部衣服了。因此你又租了一个仓库来一样进行发货。两个地方都会进行发货,那么就能够把每个仓库理解为一台独立的计算机,这样经过多台计算机完成同一任务的方式就能够被称为分布式,这样的一组计算机的集合就被称为集群post

这时候以前用一张纸质的总发货清单的数据竞争解决方式就行不通了,因此咱们须要把这张总发货清单放到云端,让你们能够经过网络进行编辑,可是每次只能一我的编辑。在这种状况下,咱们能够把两个仓库各自当作一台计算机/进程,而每一个仓库里的人就是这个进程中的线程。这样的话这张总发货清单就成为了一个分布式锁,由于它每次只能有一我的编辑,因此是一个互斥锁,或者简称为;而由于它能够被两个进程/计算机(仓库)共同使用,因此被称为是分布式锁

什么是进程/线程?

能够简单地将进程理解为咱们电脑/手机上的一个应用,同一台手机上的每一个App都是一个进程,同一个App在每一个手机上也是一个进程。进程和进程之间能够理解为是两个仓库,互相之间物理隔离;而线程就是仓库里的每个人,他们共享同一个办公空间。这里的办公空间就能够理解为操做系统中的虚拟内存空间,可是本文主要讨论并发相关的概念,就不继续展开了。

分布式数据不一致

由于生意比较好,因此全部人都很忙。有时候就会由于有一些人虽然在云端表格上已经勾上了一个订单,可是一忙就给忙忘了。其余人怕重复发货又不会再去处理已经勾上的订单了,由于这样致使的未发货订单让店铺被投诉了好屡次,影响很是大。这种在并发过程当中修改了数据状态可是没有完成后续执行的状况就会出现数据不一致,即订单已经被勾上,但实际并无发货。

可是做为聪明的老板,你又想到了解决的方法。每隔一小时两个仓库就会各派一我的检查一下已经勾上的订单是否已经都打包完贴上快递单了。这种每隔一段时间就检查并处理遗漏的数据不一致订单的任务就被称为兜底任务。而经过兜底任务实现的在最后全部订单都会达到数据一致状态的状况就被称为最终一致性

优化方式

你们可能早就以为前面介绍的总发货清单的方法太傻了,只要每一个订单都只打印一张发货清单,由单独一我的去负责分发清单就能够了,其余人只要处理好本身被分配到的订单就能够了。最后再加上一个兜底任务对订单的发货状况进行二次校验基本上就不会发生漏发或者重发的状况了。这种由一个执行器进行任务拆分,再由一组执行器进行处理,最后再由一个或一组执行器进行结果汇总的处理方式就是如今很是流行的map-reduce方法了。这种方法在大数据或者程序语言标准库里都有大量的应用,好比大数据领域赫赫有名的Hadoop和Java语言中的ForkJoinPool都使用了这种思想。

回顾

在这篇文章中,咱们涉及到了如下的技术名词:

  1. 并发,经过多个执行器同时执行一个大任务来缩短执行时间、提升执行效率的方法。
  2. 数据竞争,对一个共享数据本应独占的读取、检查、修改过程发生了并发的状况。
  3. 临界区,存在数据竞争的代码片断。
  4. 互斥锁(也能够简称为“锁”),同一时间只能由一个执行器获取的实体,用于实现对临界区的互斥(只有一个)访问。
  5. 分布式,经过多台计算机完成同一任务的方式。
  6. 集群,一组完成同一任务的机器。
  7. 分布式锁,在不一样机器/进程上提供互斥能力的锁。
  8. 数据不一致,一系列操做不具备原子性,一部分执行成功而另外一部分没有,致使不一样数据之间存在矛盾,例如订单已是发货状态,可是实际没有发货。
  9. 兜底任务,处理数据不一致状态的任务。
  10. 最终一致性,经过兜底任务或其余方式保证数据不一致的状况最终会消失。
  11. map-reduce,一种任务拆分-执行-再合并的任务执行方式,能够有效地利用多台机器、多核CPU的性能。

后记

由于并发的知识范围很大,并且对于一些抽象概念的传递必然会须要花费一些篇幅,因此这个主题将会包含一系列文章,主要覆盖如下主题:

  1. 什么是并发?
    • 抛开冗长繁杂的技术点,直接理解并发相关的各类概念。
  2. 什么是多线程?
    • 多线程是并发的一种重要形式。经过具体的多线程问题引出多线程编程中的关键点和对应的工具与知识点,轻松学会多线程编程。
  3. 经常使用工具中的并发实现
    • 经过解析知名开源工具中的并发方案实现来深刻理解并发编程实践。

有兴趣的读者能够继续关注后续的文章,在以后的文章中会有对并发编程、操做系统原语、硬件原语等等理论与实践知识的详细介绍与案例。

对数据库索引感兴趣的读者能够了解一下我以前的文章:

  1. 数据库索引是什么?新华字典来帮你 —— 理解
  2. 数据库索引融会贯通 —— 深刻
  3. 20分钟数据库索引设计实战 —— 实战
  4. 数据库索引为何用B+树实现? —— 扩展
相关文章
相关标签/搜索