可重入锁:可以对一个ReentrantLock对象多次执行lock()枷锁和unlock()释放锁。
公平锁:线程在加锁之前会查看AQS队列中有没有排队,如果有排队那么它会排到队列后面。
非公平锁:线程会直接加锁,不会查看AQS队列。
底层实现AbstractQueuedSynchronizer
ReentrantLock的两个构造方法(考虑公平策略和不考虑公平策略)
// 不考虑公平策略
public ReentrantLock() {
sync = new NonfairSync();
}
// 考虑公平策略
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
公平锁对象和非公平锁对象
// 公平锁定的同步对象
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
acquire(1);
}
// 除非递归调用或没有等待程序或是第一个,否则不赋予授予访问权限。
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
// 非公平锁的同步对象
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
// 执行锁定,立即尝试,失败时备份到正常状态
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
AQS核心结构
// 用于指示节点正在共享模式下等待的标记
// 共享模式指依据AQS的state控制状态,可以有多个满足条件的线程同时工作。
static final Node SHARED = new Node();
// 用于指示节点正在独占模式下等待的标记
// 独占模式指AQS中的state控制状态,只有一个线程能够工作(其他线程进入阻塞状态)
static final Node EXCLUSIVE = null;
// 等待队列,专门存放那些加锁的线程
// 等待队列的头,已延迟初始化。除了初始化,它只能通过方法sethead进行修改。注意:如果head存在,则保证其waitstatus不会被取消
private transient volatile Node head;
// 等待队列的尾部,已延迟初始化。仅通过方法enq修改以添加新的等待节点。
private transient volatile Node tail;
// 同步状态。可重入锁的核心,lock()+1,unlock()-1。
private volatile int state;
原子性自增demo
public class AtomicityLock {
private int count = 0;
Lock lock = new ReentrantLock();
private void increase() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
Long time = System.currentTimeMillis();
final AtomicityLock atomicityLock = new AtomicityLock();
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
public void run() {
for (int j = 0; j < 10000000; j++) {
atomicityLock.increase();
}
}
}).start();
}
while (Thread.activeCount() > 1) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("运行时间:" + (System.currentTimeMillis() - time));
System.out.println("ReentrantLock(可重入锁):" + atomicityLock.count);
}
}
版权声明:本文为qq_27243963原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。