开坑!从今天起开始看《并发编程的艺术》,这本书是经过学长的推荐才得知的,正好能让我对并发编程有更深入的了解。其实项目中已经开始遇到并发问题了,但是这方面一直没有得到系统的学习。现在忙里偷闲,赶紧补上。
PS: 特意找了一张和锁相关的图片,同时也寓意着精诚所至,金锁为开🔒
一、上下文切换#
即使是单核处理器也支持多线程执行代码,CPU 通过给每个线程分配 CPU 时间片(一般为几十毫秒)实现这个机制。
当前任务执行一个时间片后会切换到下一个任务。在切换前会保存上一个任务的状态,以便下次
切换回这个任务时,可以再加载这个任务的状态。任务从保存到再加载的过程就是一次上下文切换。
如何减少上下文切换?
- 无锁并发编程。多线程竞争锁时,会引起上下文切换,可以用一些办法避免使用锁,如将数据的 id 取模分段,不同的线程处理不同段的数据
- CAS 算法:Java 的 Atomic 包使用 CAS 算法来更新数据,不需要加锁
- 使用最少线程,避免创建不需要的线程
- 在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换
二、死锁#
避免死锁的几个常见方法:
- 避免一个线程获取多个锁
- 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
- 尝试使用定时锁,使用 lock.tryLock (timeout) 来替代使用内部锁机制
- 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况
三、资源限制的挑战#
问题:如果将某段串行的代码并发执行,因为受限于资源,仍然在串行执行,这时候程序不仅不会加快执行,
反而会更慢,因为增加了上下文切换和资源调度的时间。
如何解决:
对于硬件资源的限制,使用机群并行执行程序,通过搭建服务器集群,不同的机器处理不同的数据
对于软件资源的限制,可以考虑使用资源池将资源复用
根据不同的资源限制调整程序的并发度