2021-04-06

第一章 走进并行世界

1、临界区

表示共享资源或者共享数据

2、同步与异步

如果系统中存在临界资源(资源数量少于竞争资源的线程数量的资源),例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就必须进行同步存取(数据库操作中的排他锁就是最好的例子)。当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。事实上,所谓的同步就是指阻塞式操作,而异步就是非阻塞式操作

3、死锁、饥饿、活锁

死锁:多个线程互现持有对方手中的资源,多个线程一起进去阻塞状态

饥饿:高优先级线程插队,低优先级线程无法获得资源,但未来有可能得到解决

活锁:让路问题,线程谦让,主动释放所持有地资源,导致资源不断地在两个线程之间跳动而又无法进行下去

【面试题】死锁的解决方案:

· 死锁出现的原因是因为各个线程均不肯释放手中的资源而直接进入阻塞状态,因此可以使用可重入锁ReentrantLock的中断响应和限时等待来解决

中断响应:lock.lockInterruptibly(); 等待锁时可以被中断,中断响应逻辑中可以释放已持有的锁资源

锁申请等待限时:lock.tryLock(时间),规定时间内等不到返回false,可以采取释放锁的操作

· 释放所持有的锁并不意味着操作失败,可以在外层设置循环,再重新尝试获取锁资源,直到成功。

4、并发级别

阻塞、无饥饿、无障碍、无锁、无等待

· 无饥饿:公平锁

·无障碍:自由进出,遇到冲突回滚操作(不循环)。例如一致性标志法检测冲突

·无锁:自由进出,遇到冲突循环重试,最终总有能走出临界区的,例如CAS锁

·无等待:访问只有,修改加锁并检测冲突

5、加速比

· 加速比 = time优化前 / time优化后

· 不仅取决于CPU的核数,还取决于串行比例

6、JMM:原子性、可见性、有序性

· 原子性:

基本、引用数据类型的赋值和引用是原子性操作。

但在32位的机子中,long和double的引用和赋值则是可分割的。

· 有序性:(happen-before原则)

指令重排问题,为了减少中断流水线的次数,在汇编指令层面上。

指令重排的仅保证串行语义的一致,但没有义务保证多线程之间的语义也一直,因此多线程时不能保证有序性。

哪些指令不能重排:happen-before规则

第二章 Java并行程序基础

2.1 进程

· 进程是系统资源分配和调度的基本单位

· 进程是程序的实体

· 线程是轻量级进程,是程序执行的最小单位

· 使用多线程而不是多进程的原因?

线程间切换和调度的成本远小于进程

· 线程状态6种:new、runable、waiting、timed waiting、blocked、terminated

2.2 线程基本操作

· 不要用run方法来开启线程,他只会在当前线程中串行地执行run方法中的代码

· 创建线程三种方式

2.2.2 终止线程

· Thread.stop():太过暴力,会直接强制终止线程,并释放其持有的所有资源,包括锁,引发一致性问题

可以通过增加stopme标志和对应标志函数来实现安全的终止

2.2.3 线程中断(interrupt)

· 需要自己在run方法中增加中断处理逻辑

2.2.4 等待和通知(wait和notify)

· Object类中的方法

· 二者在使用前均需要获得目标对象的一个监视器,因此他必须被包含在synchronized语句中

· notify执行后仅唤醒在目标对象的等待队列中的线程,使其进入runable状态,但自己并不会立马释放该对象的监视器

· wait()和sleep()的区别:sleep()不会释放任何资源

2.2.5 挂起和继续执行(suspend和resume)

· suspend不会释放任何锁资源,直到调用resume

· 因此不推荐,已被弃用。若resume在suspend前执行(在不同线程中调用时会出现这种情况),则线程会一直处于挂起状态

· 可以利用wait()和notify()方法,在应用层面实现suspend()和resume()的功能(会释放锁资源)

2.2.6 等待线程结束(join)和谦让(yield)

· 线程1.join() :需先调用start方法,再用join(), 暂停当前线程,无限期等调用线程结束,也有含参方法,可设置等待时间。

其本质是让调用线程wait在线程对象实例上。

因此在应用程序中,尽量不要使用线程对象作为锁对象,避免出现错误

· yield() :让出当前cpu,进入runable状态,等待cpu重新调度,当然也可能还是他自己抢到cpu执行权

2.3 volatile与Java内存模型(JMM)

· 在虚拟机的Server模型下,由于系统优化的结果,临界区数据的修改并不一定发生能被其他线程发现

· volatile关键字:高速虚拟机,该变量是不稳定的,会在不同的线程中被修改,每次使用记得实时地去临界区看看最新的数据

· volatile保证修改可见性

2.4 分门别类管理:线程组

ThreadGroup:方便统一管理和进行一些统计

2.5 驻守后台:守护线程(Daemon)

· 是系统的守护者,负责为用户(工作)线程提供服务,例如垃圾回收线程、JIT线程就可以理解为守护线程。但一个java应用内只有守护线程时,虚拟机就会自然退出。

2.6 线程优先级

· 1-10,数值越大优先级越高

2.7 线程安全的概念与synchronized

· 作用是实现线程间的同步

· 同步代码块、同步方法、静态同步方法的锁对象

· synchronized可以保证多线程的有序性和可靠性

· synchronized既保证了可见性又保证了访问共享变量的原子性

· synchronized原理:

获得锁

清空线程变量副本

拷贝共享变量到线程变量副本

执行代码

将修改后的变量副本拷贝到共享数据区

释放锁

2.8 隐蔽的错误

· 并发下的ArrayList

数组越界问题:保存容器大小的变量被多线程不正常的访问

数据丢失问题:多个线程对容器同一个位置进行赋值

· 并发下的HashMap

jdk 1.7:多个线程操作容器,执行扩容操作的数据迁移函数transfer函数时,有可能造成数据丢失链表循环的情况

jdk 1.8:解决了之前的问题。将头插改为尾插,并将数据迁移操作合并到了resize函数中,然而在多个线程进行put操作时存在数据覆盖的问题

· 加锁的注意事项

不要把不可变类型对象当作锁对象,例如String、Integer,因为当进行拼接或计算时,这类引用会重新指向新的对象,并发操作时就可能获取到不同的对象

面试题

合适的线程数量是多少?CPU核心数和线程数的关系?

https://blog.csdn.net/qq_29860591/article/details/113618636

①CPU密集型任务:

首先,我们来看 CPU 密集型任务,比如加密、解密、压缩、计算等一系列需要大量耗费 CPU 资源的任务。对于这样的任务最佳的线程数为 CPU 核心数的 1~2 倍,如果设置过多的线程数,实际上并不会起到很好的效果。此时假设我们设置的线程数量是 CPU 核心数的 2 倍以上,因为计算任务非常重,会占用大量的 CPU 资源,所以这时 CPU 的每个核心工作基本都是满负荷的,而我们又设置了过多的线程,每个线程都想去利用 CPU 资源来执行自己的任务,这就会造成不必要的上下文切换,此时线程数的增多并没有让性能提升,反而由于线程数量过多会导致性能下降。针对这种情况,我们最好还要同时考虑在同一台机器上还有哪些其他会占用过多 CPU 资源的程序在运行,然后对资源使用做整体的平衡。

②耗时IO型任务:

第二种任务是耗时 IO 型,比如数据库、文件的读写,网络通信等任务,这种任务的特点是并不会特别消耗 CPU 资源,但是 IO 操作很耗时,总体会占用比较多的时间对于这种任务最大线程数一般会大于 CPU 核心数很多倍,因为IO 读写速度相比于 CPU 的速度而言是比较慢的,如果我们设置过少的线程数,就可能导致 CPU 资源的浪费。而如果我们设置更多的线程数,那么当一部分线程正在等待 IO 的时候,它们此时并不需要 CPU 来计算,那么另外的线程便可以利用 CPU 去执行其他的任务,互不影响,这样的话在任务队列中等待的任务就会减少,可以更好地利用资源。

作者:疯狂麦克斯鸭

链接:https://www.jianshu.com/p/26d4d667f9fd

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

推荐阅读更多精彩内容

  • 1. 介绍 JAVA作为使用的主力语言,掌握下其历史发展也是有必要的。看看从JAVA5开始到现在的JAVA9有哪些...
    孔特利亚诺阅读 165评论 0 0
  • 在文章开头先抛几个问题: 什么时候才需要分库分表呢?我们的评判标准是什么? 一张表存储了多少数据的时候,才需要考虑...
    Alice暗阅读 236评论 0 0
  • 计算机科学与另外的一些学科紧密相关。这些学科之间有明显的交叉领域,但也有明显的差异。 信息科学-信息科学是指以信息...
    屈浩宇阅读 80评论 0 0
  • 给你学习路线:html-css-js-jq-javase-数据库-jsp-servlet-Struts2-hibe...
    屈浩宇阅读 147评论 0 0
  • 夜莺2517阅读 127,709评论 1 9