一、什么是并发?
并发的本质是解决三个问题:分工、同步、互斥
- 分工:任务拆分,将一个任务拆分成多个可以同时进行的任务
- 同步:任务完成后,进行通知,告知任务已完成(线程之间如何协作)
- 互斥:任务之间互不影响(保证同一时刻只允许一个线程访问共享资源)
以生活中的事为例:一家餐馆中,一位服务员将用户点的餐告知后厨。
分工:后厨得到消息,将点菜单中的菜品分发给各厨师。
同步:厨师在完成自己的菜品后,按铃通知服务员。
互斥:一口锅在被用于一个菜品后,不能够被其他厨师使用。
二、并发程序问题源头
CPU、内存、IO设备间存在巨大的速度差异,为了平衡三者之间的这种差异,在计算机体系结构、操作系统和编译程序三个方面做了优化,这三个方面的优化引出了三个问题。
- 计算机体系结构:可见性问题
- 操作系统:原子性问题
- 编译程序:有序性问题
三、并发编程问题
并发问题可分为以下三种:安全性、活跃性和性能问题
1. 安全性
程序按期望执行
2. 活跃性
死锁
活锁
饥饿:线程因无法访问所需资源而无法执行下去的情况
3. 性能问题
3.1 性能指标:
- 吞吐量:单位时间内能处理的请求数量
- 延迟:指的是从发出请求到收到响应的时间
- 并发量:同时处理的请求数量,一般来说随着并发量的增加、延迟也会增加
3.2 方案
a. 使用无锁的算法和数据结构
常见的方案:
- 乐观锁
- 写入时复制
- Java原子类
b. 减少锁持有的时间
常见的方案:
- 减小锁的粒度
- 读写锁