我听过一句很有道理的一句话,重要的不是学会什么,重要的是学会学习的方式,这句话在java的学习中很精辟,现在的编程学习途径有很多,就拿并发编程学习的资料来说,网上一抓一大把,视频呀,学习班呀太多太多了,那在这个时候,就要选择自己最适合的方式,以前我说,喜欢姑娘的思想是,物有百味,适口者珍,学习也是一样的,不多说了,下面就说说AQS
AQS是啥,之前的文章我说过,其实他是一个抽象类的缩写,
AbstractQueuedSynchronizer 1 他的实现类有哪些
ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier
继续说说他们是怎么实现的
Semaphore 这个是信号量锁
public Semaphore(int permits) { sync = new NonfairSync(permits); } 创建他的时候,实际上是委托sync类来执行方法
abstract static class Sync extends AbstractQueuedSynchronizer 而sync类 继承了AQS所以说,Semaphore 是AQS实现类的一种
那Semaphore是干啥的呢
信号量锁像连接池 让几个先执行 然后其他几个等待这几个执行完
public static void main(String[] args) {
// 线程池
ExecutorService exec = Executors.newCachedThreadPool();
//设置信号量同时执行的线程数是5
final Semaphore semp = new Semaphore(2);
// 模拟20个客户端访问
for (int index = 0; index < 8; index++) {
final int NO = index;
exec.execute(() -> {
try {
//使用acquire()获取锁
semp.acquire();
System.out.println("Accessing: " + NO);
//睡眠1秒
Thread.sleep(2000);
} catch (InterruptedException ignore) {
} finally {
//使用完成释放锁
semp.release();
}
});
}
// 退出线程池
exec.shutdown();
}
CountDownLatch 这是一个门栓的思想,就是要等到船员齐了再一起上传
CountDownLatch latch = new CountDownLatch(10);
ExecutorService exec = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
exec.execute(() -> {
try {
int millis = new Random().nextInt(10000);
System.out.println("等待游客上船,耗时:" + millis + "(millis)");
Thread.sleep(millis);
} catch (Exception ignore) {
} finally {
latch.countDown(); // 完事一个扣减一个名额
}
});
}
// 等待检查
latch.await();
System.out.println("船长急躁了,开船!");
// 关闭线程池
exec.shutdown();
}
2 实现AQS的锁有那些
自旋锁、互斥锁、读锁写锁、条件产量、信号量、栅栏都是AQS的衍生物
栅栏是啥? 内存屏障,几乎所有的处理器至少支持一种粗粒度的屏障指令,通常被称为“栅栏(Fence)”