线程并行学习笔记

一、线程并行相关概念

同步(Synchronous)和异步(Asynchronous)

同步和异步的本质区别是是否需要等待,比如一个方法在执行,必须等前面一个方法程执行完成,才可以执行,这就是同步。如果不需要等上一个方法执行完成,并行或者并发执行,这就是异步调用。

并发(Concurrency)和并行(Parallelism)

并发和并行两个概念很容易混淆。解释起来意思也差不多,不过说起来,并行才是真正意义上的并行执行,并发只是线程的交替执行,有可能存在串行的情况。

在单核CPU的系统,线程只能是并发的,而不能支持并行,并行执行只能存在与多核CPU的系统。

临界区

临界区,可以理解为公共的资源或者说共享数据。临界区具有保护性,也就是说,只能一个线程占用临界区,一旦一个线程占了临界区,另外一个线程是不予许再占用的,必须等线程释放了才行。

阻塞(Blocking)和非阻塞(Non-Blocking)

阻塞是线程的一种比较严重的情况,从前面我们知道了临界区只能允许一个线程占用,假如一个线程因为执行时间过长,占用了临界区,不挂起,其它想要占用临界区的线程只能等待,这种情况就容易造成线程阻塞。非阻塞的话就相反了,指所有线程都正常执行,不会出现线程占临界区不挂起的情况。

饥饿(Starvation)、死锁(Deadlock)和活锁(Livelock)

饥饿,有些情况可能是一个线程优先级太低了,每次都被其它线程占用了,导致改线程一种不能占用临界区。也有一些情况是上一个线程执行时间太长了,一直没释放,导致其它线程都不能占用临界区,这也是造成线程饥饿。

死锁有可能是因为线程死循环调用等等情况造成的,一旦出现这种情况估计就得人工排查了。

活锁,解释一下,一般就是这样的情况,因为线程互相挂起临界区,给其它线程用,互相“谦让”,导致资源在两个或者几个线程之间跳到,这种情况就是活锁。

二、并行的两个重要定律

Amdahi定律

Amdahi定律定义了串行系统并行化后的加速比公式。

加速比定义:加速比 = 优化前系统耗时 / 优化后系统耗时

加速比越高,说明优化越明显。简单介绍一下Amdahi定律公式的推导。
优化后耗时T_n=T1(F+1/n(1-F)),其中T1表示优化前耗时,F表示串行比例,(1-F)表示并行比例,下标n就是处理器的个数。
导入加速比公式,也就是T1/T_n,也就是1/(F + 1/n(1-F)),公式只是进行简单介绍。

从公式可以看出,加速比是和串行比例F成反比的,从公式可以看出增加cpu的个数仅仅是一种提供加速比的方法,增加cpu个数的同时,还可以提供降低串行比例来做,也就是串行比例F越低,加速比也就越高

Gustafson定律

Custafson公式也是并行的一个比较重要的公式,现在介绍一下Custafson公式的推导。

定义一下串行执行时间为a,并行执行时间为b。即单核CPU情况,执行时间为a+b总执行时间为a+nb,n表示CPU个数。

//定义串行比例
F=a/(a+b)

//得到加速比
s(n)=a+nb/a+b=a/a+b + nb/a+b = F + n*(b-a+a)/a+b = F + n(1-F)

从公式可以看出,如果串行比例足够小的情况,加速比其实就是约等于处理器个数,也就是说通过加多CPU的个数就能提高加速比。

两个公式看起来似乎有点矛盾,其实不然,两个公式只是从不同角度分析问题。Amdahi是说在串行比例一定时,通过加CPU的方法是有上限的,通过降低串行比例同时增加cpu个数可以提高加速比。Custafson是说在串行比较趋于很小的情况,从公式可以看出,加cpu就可以提高加速比

三、多线程的特性

因为多线程环境的数据不一致性和安全性,所以就需要一些规则类控制,Java的内存模型JMM就规范了多线程有效正确的执行,而JMM也正是围绕多线程的原子性、可见性、有序性进行的,所以本博客介绍一些多线程的原子性、可见性和有序性

原子性

对于单线程来说,确实是具有原子性的,比如一个int变量,改变一下值,去读取的时候是那个值,这是很正常的,我们去系统运行,也是这样的,因为我们的操作系统大部分是32位和64位的,int类型4个字节,也就是32位,不过可以试试long类型的数值,long类型是8个字节,也就是64位,如果两个线程都对其进行读写呢?在多线程环境,一个线程改变了long类型的值,然后再去读取,获取到的值就不一定是刚才改变的值了,因为你的系统可能是32位的,而long类型是64位的,如果两个线程都对long类型进行读写,就会出现这种情况。

可见性

对于可见性又应该怎么理解?首先说一下对于单线程来说,是并不存在可见性的,可见性是针对多线程来说的,比如,一个线程进行了改变,另外一个线程是否知道这个线程做了改变,这个就是可见性。举个例子,变量a是共享变量,一个cpu1上的变量a做了缓存优化,将变量a放在了缓存里,这时,另外一个cpu2上线程对变量a做了改变,这个操作对于cpu1上的线程是不可见的,因为cpu1已经做了缓存,所以cpu1上的线程就从缓存读取变量a了,发现和cpu2上读取的值并不一致。

有序性

对于单线程来说,一个线程的代码执行是按照先后顺序的,这样说是没错的,但是在多线程环境可不一定了。因为在多线程环境可能发生指令的重排。也就是说多线程环境,代码执行是不一定具有有序性的。

既然无序性是重排导致的,那么是所有的指令都会重排的?当然不是。重排按照:Happen-Before规则。

列举一下:
引用葛一鸣/郭超/. 实战Java高并发程序设计 (597-601).

程 序 顺 序 原 则: 一 个 线 程 内 保 证 语 义 的 串 行

性 volatile 规 则: volatile 变 量 的 写, 先 发 生 于 读, 这 保 证 了 volatile 变 量 的 可 见 性

锁 规 则: 解 锁( unlock) 必 然 发 生 在 随 后 的 加 锁( lock) 前

传 递 性: A 先 于 B, B 先 于 C, 那 么 A 必 然 先 于 C

线 程 的 start() 方 法 先 于 它 的 每 一 个 动 作

线 程 的 所 有 操 作 先 于 线 程 的 终 结( Thread.join())

线 程 的 中 断( interrupt()) 先 于 被 中 断 线 程 的 代 码

对 象 的 构 造 函 数 执 行、 结 束 先 于 finalize() 方 法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,928评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,748评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,282评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,065评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,101评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,855评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,521评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,414评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,931评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,053评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,191评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,873评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,529评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,074评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,188评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,491评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,173评论 2 357

推荐阅读更多精彩内容

  • 面试必背 会舍弃、总结概括——根据我这些年面试和看面试题搜集过来的知识点汇总而来 建议根据我的写的面试应对思路中的...
    luoyangzk阅读 6,756评论 6 173
  • iOS多线程编程 基本知识 1. 进程(process) 进程是指在系统中正在运行的一个应用程序,就是一段程序的执...
    陵无山阅读 6,057评论 1 14
  • 转载自:https://halfrost.com/go_map_chapter_one/ https://half...
    HuJay阅读 6,154评论 1 5
  • Java继承关系初始化顺序 父类的静态变量-->父类的静态代码块-->子类的静态变量-->子类的静态代码快-->父...
    第六象限阅读 2,159评论 0 9
  • 如果问我对北京印象最深的是什么?我会说是北京的地铁。 刚到北京上班的时候,住在西二旗附近,要到西二旗地铁坐地铁。那...
    孟浪之言阅读 2,840评论 10 7