csdn 聊聊高并发(七)实现几种自旋锁(二)
在 聊聊高并发(六)实现几种自旋锁(一) 这篇中实现了两种基本的自旋锁:TASLock和TTASLock,它们的问题是会进行频繁的CAS操作,引发大量的缓存一致性流量,导致锁的性能不好。
对TTASLock的一种改进是BackoffLock,它会在锁高争用的情况下对线程进行回退,减少竞争,减少缓存一致性流量。但是BackoffLock有三个主要的问题:
1、还是有大量的缓存一致性流量,因为所有线程在同一个共享变量上旋转,每一次成功的获取锁都会产生缓存一致性流量
2、因为回退的存在,不能及时获取锁释放的信息,存在一个时间差,导致获取锁的时间变长
3、不能保证无饥饿,有的线程可能一直无法获取锁
这篇会实现2种基于队列的锁,来解决上面提到的三个问题。主要的思路是将线程组织成一个队列,有4个优点:
1、每个线程只需要检查它的**前驱线程**的状态,将自旋的变量从一个分散到多个,减少缓存一致性流量
2、可以即使获取锁释放的通知
3、队列提供了先来先服务的公平性
4、无饥饿,队列中的每个线程都能保证被执行到
队列锁分为两类,一类是基于有界队列,一类是基于无界队列。
基于有界队列的队列锁
先看一下基于有界队列的队列锁。 ArrayLock
有3个特点:
\1. 基于一个volatile数组来组织线程
\2. 通过一个原子变量tail来表示对尾线程
\3. 通过一个ThreadLocal
变量给每个线程一个索引号,表示它位于队列的哪个位置。