AbstractQueueSynchronizer 是 jdk 自带的一个 构建 锁 和 同步器的基类。他内部使用 CAS (compareAndSet)保证队列的原子性, 同时利用 FIFO 队列实现 线程间的竞争.将基础的同步细节放在抽象类里面。想 countDownLatch,semaphore,CyclicBarrier ,reentrantLock都是依赖 aqs 实现的。
实现代码
public class SelfSynchronizedAqs {
private static class Sync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
int state = getState();
if (state == 0) {
System.out.println("arg = 状态错误");
return false;
}
setState(0);
setExclusiveOwnerThread(null);
return true;
}
}
Sync sync = new Sync();
public void lock(){
sync.acquire(1);
}
public void unLock(){
sync.release(1);
}
}
具体测试代码
/**
* @author yueye
* @date 2020/3/9 17:40
* @desc
*/
public class TestSelfAqsByCountLatch {
static int a = 0 ;
/**
* 比线程数量多一个原因是 务必保证 所有的线程全部执行完(a++) 操作,而且只执行一次
*
*/
static int num = 31;
// private static CyclicBarrier barrier = new CyclicBarrier(31);
private static CountDownLatch barrier = new CountDownLatch(num);
private static SelfSynchronizedAqs selfSynchronizedAqs = new SelfSynchronizedAqs();
public static void main(String[] args) throws Exception {
for (int i = 0; i < 30; i++) {
Thread thread = new Thread((() -> {
for (int j = 0; j < 10000; j++) {
increment();
}
try {
barrier.countDown();
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}));
thread.start();
}
barrier.countDown();
barrier.await();
barrier = new CountDownLatch(num);
// 等待一会 防止 创建线程过快
System.out.println(System.currentTimeMillis() + "aaaaaaaaaaaaaaaaaaaaaaaaa= " + a);
a = 0;
int w = 0;
for (int i = 0; i < 30; i++) {
Thread thread = new Thread(() -> {
for (int j = 0; j < 10000; j++) {
increment2();
}
try {
barrier.countDown();
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
});
w ++;
thread.start();
}
barrier.countDown();
barrier.await();//等30个线程累加完毕
System.out.println(System.currentTimeMillis() + "bbbbbbbbbbbbbbbbbbbb = " + a);
}
private static void increment2() {
selfSynchronizedAqs.lock();
a++;
selfSynchronizedAqs.unLock();
}
private static void increment() {
a++;
}
}
输出结果
1583749759633aaaaaaaaaaaaaaaaaaaaaaaaa= 292263
1583749759686bbbbbbbbbbbbbbbbbbbb = 300000