AQS原理

底层使用如下组件

private volatile int state;
//标识同步状态,第一次加锁时设置为1,若重入加锁,则state递增。释放锁时state递减,若state=0时将owner设置为null,并且使用LockSupport.unpark(s.thread);方法唤醒等待队列中的第一个线程
//其他线程来获取锁时,若失败,则加入等待队列(双向链表),并且使用LockSupport.park(this);休眠此线程

private transient Thread exclusiveOwnerThread;
//标识当前线程所有者

//一个双向链表作为一个队列来使用,存放等待队列(保存待加锁的线程)。

//非公平锁:新来一个线程直接判断能不能加锁,若能加锁则直接加锁,不能加锁才放入等待队列
//公平锁:等待队列中的线程依次加锁,体现的“公平”的特点

ReentratLock

多个线程争抢锁

尝试加锁,public boolean tryLock(long timeout, TimeUnit unit) 如果加锁不成功,则等待一段时间不成功则设置当前线程waitstate为SIGNAL状态,并持续重试,若最终超过了等待时间则从队列中移除

ReentrantReadWriteLock读写锁

使用state的高低16位(因为int是32位)来标识读锁(高16位)写锁(低16位),非0表示已经加过锁了

读锁,可以同时被多个线程同时持有。读请求可以并发起来

写锁,则是互斥的

Condition

可重入锁可以创建Condition,主要有2个方法await与notify/notifyAll。 await等待唤醒,await与notify/notifyAll唤醒对应conditionawait的线程。

Condition.await()原理:将自己加入condition等待队列、释放锁、挂起自己

如果在加锁等待队列里有人阻塞,会有unpark的过程,唤醒加锁等待队列中的队头元素的那个过程

signal唤醒的过程,大概的意思,就是把condition等待队列中的元素,转化为一个加锁等待队列中的元素