JAVA锁分析之AQS

1、AQS基本结构,公平锁非公平锁皆继承此类实现,竞争资源的线程封装成Node以链表的形式存在AbstractQueuedSynchronizer中,head是第一个等待线程,tail是最后一个;线程的等待存放在ConditionObject中

public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {
    private transient volatile Node head;//第一个等待的线程
    private transient volatile Node tail;//最后一个等待的线程
    private volatile int state;//锁的状态,0未被占用,大于0被占用
}
public abstract class AbstractOwnableSynchronizer implements java.io.Serializable {
	private transient Thread exclusiveOwnerThread;//当前占用锁的线程
}
public class ConditionObject implements Condition, java.io.Serializable {
    private static final long serialVersionUID = 1173984872572414699L;
    /** First node of condition queue. */
    private transient Node firstWaiter;
    /** Last node of condition queue. */
    private transient Node lastWaiter;
}    
static final class Node {
    volatile int waitStatus;//等待状态
    volatile Node prev; //上一个等待线程
    volatile Node next;//下一个等待线程
    volatile Thread thread;//当前线程
    Node nextWaiter;//await线程
}

2、锁的获取:通过CAS算法,如果state设置成1成功则执行,如果获取失败压入等待队列并LockSupport.park

lock.lock();
->sync.lock();  //sync:NonfairSync
  ->if (compareAndSetState(0, 1))
    ->compareAndSetState(int expect, int update)   //应该是个CAS算法
      ->return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    ->setExclusiveOwnerThread(Thread.currentThread());  --Sets the thread that currently owns exclusive access.
  ->else
    ->acquire(1);
      ->if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
       ->protected final boolean tryAcquire(int acquires)  //NonfairSync
         ->return nonfairTryAcquire(acquires);   //ReentrantLock
       ->addWaiter(Node.EXCLUSIVE)   //扔到等待区域
         ->Node node = new Node(Thread.currentThread(), mode);
         ->Node pred = tail;
         ->if (pred != null)
           ->node.prev = pred;
           ->if (compareAndSetTail(pred, node))   //通过CAS将新Node赋值给tail
             ->pred.next = node;
             ->return node;
         ->return node;
       ->final boolean acquireQueued(final Node node, int arg)  //AbstractQueuedSynchronizer
         ->for (;;)
           ->final Node p = node.predecessor();
           ->if (p == head && tryAcquire(arg))
             ->setHead(node);
             ->p.next = null; // help GC
             ->failed = false;
             ->return interrupted;
           ->if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())
             ->private static boolean shouldParkAfterFailedAcquire(Node pred, Node node)
               ->
             ->private final boolean parkAndCheckInterrupt()
/*==================== 暂停线程 ====================================*/
               ->LockSupport.park(this);  
               ->return Thread.interrupted();
             ->interrupted = true;
       ->selfInterrupt();
         ->Thread.currentThread().interrupt();

3、锁的释放:通过tryRelease释放锁,通过unparkSuccessor唤醒下一个线程

lock.unlock();
->sync.release(1); 
  ->if (tryRelease(arg))   //AbstractQueuedSynchronizer
    ->boolean tryRelease(int releases)
      ->int c = getState() - releases;
      ->if (Thread.currentThread() != getExclusiveOwnerThread())  throw new IllegalMonitorStateException();
      ->if (c == 0)
        ->free = true;
        ->setExclusiveOwnerThread(null);
     ->setState(c);
     ->return free;
    ->Node h = head;
    ->if (h != null && h.waitStatus != 0) unparkSuccessor(h)
      ->int ws = node.waitStatus;
      ->if (ws < 0)
        ->compareAndSetWaitStatus(node, ws, 0);
      ->Node s = node.next;
      ->if (s != null)
        ->LockSupport.unpark(s.thread);  //unpark:唤醒

4、线程等待

ConditionObject.await()
->Node node = addConditionWaiter();
  ->Node node = new Node(Thread.currentThread(), Node.CONDITION);
  ->lastWaiter = node;
->int savedState = fullyRelease(node);
->while (!isOnSyncQueue(node))
  ->LockSupport.park(this)

5、唤醒线程

ConditionObject.signal()
->Node first = firstWaiter;
->doSignal(first);
  ->transferForSignal(first)
    ->if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
      ->LockSupport.unpark(node.thread);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值