AQS源码阅读感想

1.AQS核心原理

--AQS拥有变量state,通过CAS设定state得值是否成功判断是否获得锁,源码如下:

compareAndSetState(c, nextc)
protected final boolean compareAndSetState(int expect, int update) {
    return unsafe.compareAndSwapInt(this, stateOffset, expect, update);//stateOffset可以理解为state变量的地址,state的预期是expect,设为update
}

--获得锁失败,则加入AQS的等待队列,然后挂起,挂起通过:

LockSupport.park(this);
public static void park(Object blocker) {
    Thread t = Thread.currentThread();
    setBlocker(t, blocker);
    UNSAFE.park(false, 0L);
    setBlocker(t, null);
}

--释放锁,则唤醒等待队列的下一个节点,唤醒通过:

LockSupport.unpark(s.thread);

2.AQS基于CLH锁,CLH锁和MCS锁得区别

CLH锁是轮询前一个节点的isLock属性是否为false,来判断前一个节点是否释放锁,如果释放了,自己获得锁

A<-B<-C

B节点得pre指针指向A,.轮询A得isLock属性

MCS锁是轮询自己的isLock属性是否为false,

A->B->C

A得next指针指向B,A释放锁时将B得isLock设为false

3.ReentrantLock的公平锁与非公平锁得区别:

!hasQueuedPredecessors()

公平锁判断可以占有锁得时候判断是否有等待队列,有的话插入队列,非公平锁会抢占一下试试,不判断是否有等待队列

4.CountDownLatch原理

1.CountDownLatch得构造函数传入一个int->将AQS得state设为int

2.主线程调用await(),判断state是否为0,不为零则加入AQS得等待队列挂起:LockSupport.park(this)

3.从线程每调用一次countDown,将state-1,当state减为0,则唤醒AQS队列

5.CountDownLatch,CyclicBarrier和Semaphore区别

CountDownLatch:一个主线程,N个从线程,主线程等待从线程都执行完countDown,主线程继续: 1等N,然后1继续

CyclicBarrier:N个线程,每个调用await,当大家都调用await之后,每个线程继续:N个线程,先调用await的等待,最后一个调用完,大家一起往下走

Semaphore:锁有数量限制,设定n个锁,每个线程可以一次取m个锁,不够就等待,够了就继续

发布了138 篇原创文章 · 获赞 10 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/idealemail/article/details/103991240