写在前面
并发编程是Java程序员最重要的技能之一,也是最难掌握的一种技能。现在几乎100%的公司不但面试都必须问到并发编程,而且在日常工作和开发当中更是需要并发编程的使用,尤其是在互联网公司,它要求编程者对计算机最底层的运作原理有深刻的理解,同时要求编程者逻辑清晰、思维缜密,这样才能写出高效、安全、可靠的多线程并发程序。
并发编程笔记
计算机领域从来都不乏变革,每一次都带来新的机遇与挑战。“并发编程” 无疑是一场令人激动的变革。迎接技术变革与挑战,是软件开发者的空气和水。很高兴你已经读到了这里,那么请不要停下来,继续享受挑战的乐趣,继续面对这场变革,前进吧!
- 进程
- 线程
- 并发
- 并行
进程与线程
进程
- 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理IO的
- 当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。
- 进程就可以视为程序的一个实例。大部分程序可以同时运行多个实例进程(例如记事本、画图、浏览器等),也有的程序只能启动一个实例进程(例如网易云音乐、360 安全卫士等)
线程
- 一个进程之内可以分为到多个线程。
- 一个线程就是一个指令流 ,将指令流中的一条条指令以一定的顺序交给CPU执行
- Java中,线程作为最小调度单位,进程作为资源分配的最小单位。在windows中进程是不活动的,只是作为线程的容器
并行与并发
(由于内容太多了,为了不影响大家的阅读体验,以下大量内容省略......Σ( ° △ °|||)︴)
并发编程共享模型篇
共享模型之管程
共享带来的问题
共享模型之内存
退不出的循环
共享模型之无锁
CAS与volatile
CAS的特点
共享模型之不可变
日期转换的问题
共享模型之工具
线程池
ThreadPoolExecutor
Executor线程配置
线程安全集合类概述
并发编程之原理篇
指令级并行原理
SuperScalar处理器
CPU缓存结构原理
.CPU缓存结构
CPU缓存一致性
MESI协议
- E、 S、M状态的缓存行都可以满足CPU的读请求
- E状态的缓存行,有写请求,会将状态改为M,这时并不触发向主存的写
- E状态的缓存行,必须监听该缓存行的读操作,如果有,要变为S状态
volatile原理
volatile的底层实现原理是内存屏障,Memory Barrier ( Memory Fence )
- 对volatile变量的写指令后会加入写屏障
- 对volatile变量的读指令前会加入读屏障
如何保证可见性
final原理
Monitor原理
Monitor被翻译为监视器或管程
每个Java对象都可以关联一个Monitor对象,如果使用synchronized给对象上锁(重量级)之后,该对象头的Mark Word中就被设置指向Monitor对象的指针
synchronized原理进阶
轻量级锁
- 轻量级锁的使用场景:如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争) , 那么可以使用轻量级锁来优化。
- 轻量级锁对使用者是透明的,即语法仍然是synchronized
- 假设有两个方法同步块利用同一个对象加锁
自旋优化
重量级锁竞争的时候,还可以使用自旋来进行优化,如果当前线程自旋成功(即这时候持锁线程已经退出了同步块,释放了锁), 这时当前线程就可以避免阻塞。
偏向锁
- 轻量级锁在没有竞争时(就自己这个线程), 每次重入仍然需要执行CAS操作。
- Java 6中引入了偏向锁来做进一步优化: 只有第一次使用CAS将线程ID设置到对象的Mark Word头之后发现这个线程ID是自己的就表示没有竞争,不用重新CAS。以后只要不发生竞争,这个对象就归该线程所有
wait notify原理
park unpark原理
每个线程都有自己的一一个Parker对象
- 线程就像一个旅人,Parker就像他随身携带的背包,条件变量就好比背包中的帐篷。counter 就好比背包中的备用干粮(0为耗尽,1为充足)
- 调用park就是要看需不需要停下来歇息
如果备用干粮耗尽,那么钻进帐篷歇息. 如果备用干粮充足,那么不需停留,继续前进
- 调用unpark,就好比令干粮充足
如果这时线程还在帐篷,就唤醒让他继续前进 如果这时线程还在运行,那么下次他调用park时,仅是消耗掉备用干粮,不需停留继续前进
ReentrantLock原理
条件变量实现原理
每个条件变量其实就对应着一个等待队列 ,其实现类是ConditionObject
读写锁原理
(以上省略大量图文内容.......,Σ( ° △ °|||)︴)
Semaphore原理
Semaphore有点像一个停车场, permits就好像停车位数量,当线程获得了permits就像是获得了停车位,然后停车场显示空余车位减一
为什么要有PROPAGATE
LinkedBlockingQueue原理
并发编程之模式篇
同步模式之保护性暂停
即Guarded Suspension,用在一个线程等待另一个线程的执行结果
要点
- 有一个结果需要从一个线程传递到另一个线程,让他们关联同一个GuardedObject
- 如果有结果不断从一个线程到另一个线程那么可以使用消息队列(见生产者/消费者)
- JDK中, join的实现、Future的实现,采用的就是此模式
- 因为要等待另一方的结果,因此归类到同步模式
同步模式之顺序控制
固定运行顺序
交替输出
异步模式之生产者/消费者
定义
异步模式之工作线程
创建多少线程池合适
自定义线程池
终止模式之两阶段终止模式
两阶段终止模式
线程安全单例
享元模式
BATJ并发编程高频面试题
- 现在几乎100%的公司面试都必须面试并发编程,尤其是互联网公司,对于并发编程的要求更高,并发编程能力已经成为职场敲门砖。
- 现在已经是移动互联和大数据时代,对于应用程序的性能、处理能力、处理时效性要求更高了,传统的串行化编程无法充分利用现有的服务器性能。
- 并发编程是几乎所有框架的底层基础,掌握好并发编程更有利于我们学习各种框架。想要让自己的程序执行、接口响应、批处理效率更高,必须使用并发编程。
- 并发编程是中高级程序员的标配,是拿高薪的必备条件。
借用Java并发编程实践中的话”编写正确的程序并不容易,而编写正常的并发程序就更难了”,相比于顺序执行的情况,多线程的线程安全问题是微妙而且出乎意料的,因为在没有进行适当同步的情况下多线程中各个操作的顺序是不可预期的,下面算是对多线程情况下同步策略的一个简单介绍。
这份【并发编程】【并发编程之模式篇】【并发编程之原理篇】【并发编程之应用篇】文档共有390页,需要完整版的朋友,可以转发此文关注公众号
当然,单单有文档看是远远不够的,还有视频和相匹配的课件进行学习提升,努力把并发编程这一块儿给搞明白,相信一定会有不凡的人生!!