Note -《并发编程实战》
javajava大约 2 分钟
并发问题产生的背景
提示
CPU、内存、I/O三者的速度差异巨大,为了合理利用 CPU 的高性能,平衡这三者的速度差异,计算机体系结构、操作系统、编译程序都做出了贡献,主要体现为以下几点
- CPU增加缓存,平衡与内存之间的速度差异(带来了
可见性问题) - 操作系统增加进程、线程,通过分时复用CPU,提升CPU使用率以及改善IO操作速度差异(带来了
原子性问题) - 编译程序优化执行执行顺序,使得缓存使用效率更高(带来了
有序性问题)
三特性说明
- 可见性:多个线程对共享变量的操作相互可见
- 原子性:1个或多个操作在CPU执行过程中不被中断
- 有序性:程序按照代码的先后顺序执行
在平衡CPU、内存、I/O三者的速度差异的同时,打破了这三个特性 所以每一种高级编程语言在设计之初就需要考虑如何通过自己的方式来解决这三种并发问题
可见性问题
问题原因:
CPU引入缓存后,多核系统下,多线程操作同一个变量,多个CPU间的缓存相互不可见
解决方案:JMM(volatile、synchronized、happens-before)
原子性问题
问题原因:
高级语言的一条语句在CPU中会有多个CPU操作,多线程情况下,多个线程操作同一个变量 此时发生线程切换,则会出现类似丢失修改的问题
解决方案:互斥锁(synchronized)
有序性问题
问题原因:
一条语句在CPU执行前被编译优化改变了顺序
解决方案:JMM(volatile)
管程
管理共享变量,对共享变量进行安全的并发操作的过程
- 并发编程的万能钥匙,将共享变量操作统一封装
- 解决互斥、同步问题
- Java 1.5之前的管程经典实现:synchronized
为什么要Lock
既生Synchronized,何生Lock
Synchronized的痛点:
- 性能问题(1.6优化解决)
- 死锁不可抢占问题(Synchronized在申请资源时,如果申请不到则会进入阻塞状态,也无法释放已经占有的共享资源)
新锁Lock的特性:必须要可以破坏不可抢占条件
- 能够响应中断:lockInterruptibly( )
- 支持超时:tryLock(long time, TimeUnit unit)
- 非阻塞的获取锁:获取锁失败后直接返回并释放其他占用资源 tryLock()
Powered by Waline v2.14.1