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个锁,不够就等待,够了就继续