Skip to content

csdn 聊聊高并发(七)实现几种自旋锁(二)

聊聊高并发(六)实现几种自旋锁(一) 这篇中实现了两种基本的自旋锁:TASLock和TTASLock,它们的问题是会进行频繁的CAS操作,引发大量的缓存一致性流量,导致锁的性能不好。

对TTASLock的一种改进是BackoffLock,它会在锁高争用的情况下对线程进行回退,减少竞争,减少缓存一致性流量。但是BackoffLock有三个主要的问题:

1、还是有大量的缓存一致性流量,因为所有线程在同一个共享变量上旋转,每一次成功的获取锁都会产生缓存一致性流量

2、因为回退的存在,不能及时获取锁释放的信息,存在一个时间差,导致获取锁的时间变长

3、不能保证无饥饿,有的线程可能一直无法获取锁

这篇会实现2种基于队列的锁,来解决上面提到的三个问题。主要的思路是将线程组织成一个队列,有4个优点:

1、每个线程只需要检查它的**前驱线程**的状态,将自旋的变量从一个分散到多个,减少缓存一致性流量

2、可以即使获取锁释放的通知

3、队列提供了先来先服务的公平性

4、无饥饿,队列中的每个线程都能保证被执行到

队列锁分为两类,一类是基于有界队列,一类是基于无界队列。

基于有界队列的队列锁

先看一下基于有界队列的队列锁。 ArrayLock有3个特点:

\1. 基于一个volatile数组来组织线程

\2. 通过一个原子变量tail来表示对尾线程

\3. 通过一个ThreadLocal变量给每个线程一个索引号,表示它位于队列的哪个位置。