-
AQS 是什么
简单来说,就是来说就是一个数+一个FIFO的双端队列
如图所示:
当state成为我们想要的值,线程可以进行运行,否则进行排队在CLH末尾加入,state使用cas算法进行操作,可以解决并发时的安全问题。 -
CAS 是一种比较交换算法,现代的计算机的CPU有这条指令,jdk5.0后,jdk提供了使用的方式,大概的逻辑就是如果另一个线程看到的值还是expect,代表没有被其他线程修改,然后进行update操作。
/**
* Atomically sets synchronization state to the given updated
* value if the current state value equals the expected value.
* This operation has memory semantics of a {@code volatile} read
* and write.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that the actual
* value was not equal to the expected value.
*/
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
- synchronized
是java中加锁的关键字,在jdk1.6之后的版本对其进行了优化,首先一个线程获得了锁,锁就进入了偏向,如果锁偏向失败,锁会升级为轻量级锁(大多数是自旋锁,执行几次空的循环,等待可以获取锁),再失败就是悲观锁synchronized。
同时synchronized的锁是需要jvm调用操作系统底层进行实现,再用户态和kernel中进行切换,消耗时间。
- AQS 使用场景
具体的使用需要继承AbstractQueuedSynchronizer重写其中的tryAcquire和tryRelease方法,实例如下:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
public class LockDemo {
private static Sync sync = new Sync();
private static volatile int m = 0;
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
try {
sync.acquire(1);
for (int j = 0; j < 100; j++) {
m++;
}
} finally {
sync.release(1);
}
});
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
System.out.println(m);
}
private static class Sync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
//0: 没有占有 1: 占用
if (compareAndSetState(0, 1)) {
//互斥锁
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
if (!isHeldExclusively()) {
throw new IllegalMonitorStateException();
}
setExclusiveOwnerThread(null);
setState(0);
return true;
}
@Override
protected boolean isHeldExclusively() {
//是否被当前线程独占
return getExclusiveOwnerThread() == Thread.currentThread();
}
Condition newCondition() {
return new ConditionObject();
}
// Deserializes properly
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); // reset to unlocked state
}
}
}
- AQS 实际应用
ReetrantLock
CountDownLatch
Semaphore
ReetrantReadWriteLock
这些都是底层都是使用的AQS