一、公平策略
在多个线程争用锁的情况下,公平策略倾向于将访问权授予等待时间最长的线程。也就是说,相当于有一个线程等待队列,先进入等待队列的线程后续会先获得锁,这样按照“先来后到”的原则,对于每一个等待线程都是公平的。
场景分析:
1.持有锁的线程A正在running,对列中有线程BCDE被挂起并等待被唤醒;
2.线程E执行lock,队列中有线程BCD在等待,线程E直接加入到队列的队尾。
实践示例:
输出:
我们一共定义了A、B、C、D、E共五个线程,在runThead()方法中循环执行3次加锁和解锁的过程。从多次执行的结果来看他们始终按照A-B-C-D-E的顺序输出。
二、非公平策略
在多个线程争用锁的情况下,能够最终获得锁的线程是随机的(由底层OS调度)。
场景分析:
1.线程A和B同时执行CAS指令,假设线程A成功,线程B失败,则表明线程A成功获取锁,并把同步器中的exclusiveOwnerThread设置为线程A。
2.竞争失败的线程B,在nonfairTryAcquire方法中,会再次尝试获取锁,也就是在这段时间如果线程A释放锁,线程B就可以直接获取锁而不用挂起。完整的执行流程如下:
实际示例:
输出:
我们同样定义了A、B、C、D、E共五个线程,在runThead()方法中循环执行3次加锁和解锁的过程。从多次执行的结果来看输出的顺序没有规律可言,完全是随机不可预知的。