锁的概述(二)--公平锁与非公平锁

2022-12-01 08:47:47

1 简介

根据线程获取锁的抢占机制,锁可以分为公平锁和非公平锁。

  • 公平锁:获取锁的顺序按照线程请求锁的时间顺序决定,ji简单来说,早申请早获取到锁,晚申请晚获取到锁。
  • 非公平锁:获取锁的顺序不一定按照请求锁的时间来决定,早申请不一定先得到锁。

2 实现

ReentrantLock 提供了公平锁与非公平锁的实现:

  • 公平锁:ReentrantLock pairLock = new ReentrantLock(true);
  • 非公平锁:ReentrantLock pairLock = new ReentrantLock(false);
    没有公平性需求尽量使用非公平锁,公平锁会带来额外的性能开销。

3 原理

ReentrantLock 的公平锁和非公平锁最终都委托抽象同步队列AQSacquire()来获取

//AbstractQueuedSynchronizer#acquirepublicfinalvoidacquire(int arg){//抽象方法,实现类去实现该方法if(!tryAcquire(arg)&&//acquireQueued():多次尝试获取锁或者阻塞//addWaiter():将线程结点加入到等待队列acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//线程中断,调用`Thread.currentThread().interrupt()` 中断线程selfInterrupt();}

3.1 公平锁

//锁finalvoidlock(){acquire(1);}protectedfinalbooleantryAcquire(int acquires){final Thread current= Thread.currentThread();//获取当前可重入次数int c=getState();if(c==0){//检查是否有等待队列,采用公平策略 核心在此if(!hasQueuedPredecessors()&&compareAndSetState(0, acquires)){setExclusiveOwnerThread(current);returntrue;}}//当前线程是该锁的持有者elseif(current==getExclusiveOwnerThread()){int nextc= c+ acquires;if(nextc<0)thrownewError("Maximum lock count exceeded");setState(nextc);returntrue;}returnfalse;}publicfinalbooleanhasQueuedPredecessors(){
        Node t= tail; 
        Node h= head;
        Node s;//1.如果该线程由前驱结点返回 true,//2.否则,如果当前 AQS 队列为空或者当前线程结点是第一个结点返回 falsereturn h!= t&&((s= h.next)== null|| s.thread!= Thread.currentThread());}

3.2 非公平锁

//锁finalvoidlock(){//lock 时候,随机抢占,直接进行加锁操作,而公平锁是直接调用 acquire(1)if(compareAndSetState(0,1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);}finalbooleannonfairTryAcquire(int acquires){final Thread current= Thread.currentThread();int c=getState();if(c==0){//随机抢占if(compareAndSetState(0, acquires)){setExclusiveOwnerThread(current);returntrue;}}elseif(current==getExclusiveOwnerThread()){int nextc= c+ acquires;if(nextc<0)// overflowthrownewError("Maximum lock count exceeded");setState(nextc);returntrue;}returnfalse;}
  • 作者:soleil雪寂
  • 原文链接:https://blog.csdn.net/qq_44947117/article/details/104335603
    更新时间:2022-12-01 08:47:47