Lock
简介
Lock位于 java.util.concurrent 包下,本质上Lock仅仅是一个接口。可以实现公平锁和非公平锁,默认非公平锁。
在java.util.concurrent.locks包中有很多Lock的实现类,常用的有ReentrantLock、ReadWriteLock(实现类ReentrantReadWriteLock)
包含方法:
//尝试获取锁,获取成功则返回,否则阻塞当前线程 void lock(); //尝试获取锁,线程在成功获取锁之前被中断,则放弃获取锁,抛出异常 void lockInterruptibly() throws InterruptedException; //尝试获取锁,获取锁成功则返回true,否则返回false boolean tryLock(); //尝试获取锁,若在规定时间内获取到锁,则返回true,否则返回false,未获取锁之前被中断,则抛出异常 boolean tryLock(long time, TimeUnit unit) throws InterruptedException; //释放锁 void unlock(); //返回当前锁的条件变量,通过条件变量可以实现类似notify和wait的功能,一个锁可以有多个条件变量 Condition newCondition();
实现原理
观察ReentrantLock把所有Lock接口的操作都委派到一个Sync类上,该类继承了AbstractQueuedSynchronizer
static abstract class Sync extends AbstractQueuedSynchronizer
Sync又有两个子类:
final static class NonfairSync extends Sync final static class FairSync extends Sync
核心实现依赖java.util.concurrent.AbstractQueuedSynchronizer类。
内部维护一个volatile修饰的state状态变量和CLH虚拟队列(双向链表)

锁实现(加锁)
AbstractQueuedSynchronizer会把所有的请求线程构成一个CLH队列,当一个线程执行完毕(lock.unlock())时会激活自己的后继节点,但正在执行的线程并不在队列中,而那些等待执行的线程全部处于阻塞状态,经过调查线程的显式阻塞是通过调用LockSupport.park()完成,而LockSupport.park()则调用sun.misc.Unsafe.park()本地方法,再进一步,HotSpot在Linux中通过调用pthread_mutex_lock函数把线程交给系统内核进行阻塞;如果已经存在Running线程,则新的竞争线程会被追加到队尾,具体是采用基于CAS的Lock-Free算法,因为线程并发对Tail调用CAS可能会导致其他线程CAS失败,解决办法是循环CAS直至成功。
一个虚拟队列,不存在队列实例,仅存在节点之间的前后关系;当有线程竞争锁时,该线程会首先尝试获得锁,这对于那些已经在队列中排队的线程来说显得不公平,这也是非公平锁的由来。
区别
自定义Lock
public class MyCustomLock implements Lock { private Helper helper = new Helper(); //定义内部类继承AQS private class Helper extends AbstractQueuedSynchronizer{ //获取锁 @Override protected boolean tryAcquire(int arg) { int state = getState(); if (state == 0){ if (compareAndSetState(0,arg)){ setExclusiveOwnerThread(Thread.currentThread()); return true; } }else if(getExclusiveOwnerThread() == Thread.currentThread()){ setState(getState() + arg); return true; } return false; } //释放锁 @Override protected boolean tryRelease(int arg) { int state = getState()-arg; boolean flag = false; //判断state是否为0,为0则表示释放锁 if (state == 0){ setExclusiveOwnerThread(null); setState(state); return true; } setState(state); return false; } protected Condition newCondition(){ return new ConditionObject(); } } @Override public void lock() { helper.acquire(1); } @Override public void lockInterruptibly() throws InterruptedException { helper.acquireInterruptibly(1); } @Override public boolean tryLock() { return helper.tryAcquire(1); } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return helper.tryAcquireNanos(1,unit.toNanos(time)); } @Override public void unlock() { helper.release(1); } @Override public Condition newCondition() { return helper.newCondition(); } }

浙公网安备 33010602011771号