AQS分层及自定义锁

之前写了一些锁使用文章,比如ReentrantLock(独占锁),ReentrantReadWriteLock(读写锁)等,也写了一些线程通讯类Condition(条件队列),CountDownLatch(倒计时器),CyclicBarrier(循环栅栏),Semaphore(信号量)等,底层都是使用AQS实现的。本篇文章主要记录AQS内部变量方法的使用及作用,还使用AQS实现了自定义锁的实现。比较简单,如需编写复杂的自定义锁也可以参考ReentrantLock(独占锁),ReentrantReadWriteLock(读写锁)。

阅读更多

Condition原理解析

在之前介绍ReentrantLock锁使用文章中,简单的介绍了Condition在ReentrantLock中的使用,Condition主要用作线程之间的通信,等待,唤醒等功能,但是Condition是如何实现线程之间的通信的呢?本篇文章会罗列出所有Condition的API,然后介绍每个APi的功能并且描述Condition底层的实现原理。

阅读更多

ReentrantReadWriteLock原理解析

前面在介绍ReentrantLock提到过SHARED锁和EXCLUSIVE锁,我们使用ReentrantLock的时候,虽然因为自旋效率较高,但有些情况下我们不必要使用独占锁,比如读写场景,读较多,写较少,可以让多个线程同时取读,当有线程写的时候让其余的读写线程等待即可。这样提高了读的效率。ReentrantReadWriteLock从名字来看就是读写锁,读读共享,读写互斥。

阅读更多

CyclicBarrier使用

上一篇文章使用CountDownLatch模拟一家人出行旅行的计数器模型,也可以使用CyclicBarrier实现,CyclicBarrier翻译成英文为循环栅栏,CyclicBarrier的内部原理与CountDownLatch基本一样。不同地方在于CountDownLatch使用Node管理线程中断,而CyclicBarrier使用Condition队列。其实内部都一样。文章记录CyclicBarrier的使用过程以及其内部实现原理,供后续使用,复习,复盘等。

阅读更多

Semaphore使用

Semaphore是一个计数信号量,常用于限制可以访问某些资源(物理或逻辑的)线程数目。比如我们的接口只能同时有1000个连接访问,比如停车场只能停50辆车等等,Semaphore内部通过AQS实现公平锁和非公平锁。

阅读更多

CountDownLatch使用

项目开发中有一些需求,比如需要一些线程执行完成后再去执行一些操作。此时就需要用到CountDownLatch这个类,CountDownLatch是一个计数器,每当执行一个任务完成时调用计数器减一,直到count=0时才会执行后续的线程。CountDownLatch中的count不可重置。如果需要对count进行重置,官方建议使用CyclicBarrier,在后面的文章中会进行使用介绍。

阅读更多

ReentrantLock使用

之前有篇文章分析了Synchronized如何锁以及锁升级的过程,我们可以使用Synchronized来保证线程安全,为什么Java还设计一个AQS的东西来保证线程安全呢?我也不是特别清楚,一边读源码,一边梳理。本文主要记录ReentrantLock的使用及部分源码的梳理过程。

阅读更多

LongAdder及Striped64解析

Java原子类原理解析文章中写过一个原子的累加计算,AtomicInteger使用CAS的方法保证了原子性。也在ABA问题原理解析文章中阐述了关于AtomicInteger的ABA问题。以及如何解决ABA问题。那么有没有办法解决多线程对一个变量循环竞争导致的CPU空转。标题中的LongAdder就是解决方案之一。

阅读更多

ABA问题原理解析

AtomicReference使用

上一篇文章阐述了AtomicInteger如何保证线程安全,在Atomic包下还有AtomicLong,AtomicBoolean及相对应的数据包装类保证了线程安全,但是这些都是Java基础数据类型,如果需要操作的是一个自定义对象,就要使用到AtomicReference。它是一个可以自动更新的对象引用。

阅读更多