JUC常用工具类源码分析
ReentrantLock
一个可重入,可多条件变量,可超时的锁
new
java
1 | // 无参非公平 |
Node
java
1 | static final class Node { |
lock-非公平
java
1 | // 无参构造器是非公平锁 |
lock-公平
java
1 | // 非公平锁,抢锁的时候并不是上来就抢,而是判定队列中是否有其他node,并且这个owner不是自己,就不会去抢占 |
unlock
java
1 | public void unlock() { |
ConditionObject
java
1 | public class ConditionObject implements Condition, java.io.Serializable { |
await
java
1 | // 需要获取到当前owner才能await |
signal
java
1 | public final void signal() { |
ReentrantReadWriteLock
读锁不能升级写锁(读锁里面不能重入写锁, 会卡死),写锁可以降级读锁
多条件、可重入、读读并发、读写互斥
写锁读锁各占一半state, 高16位读锁,低16位写锁
new
java
1 | public class ReentrantReadWriteLock |
Sync
java
1 | abstract static class Sync extends AbstractQueuedSynchronizer { |
公平-非公平区别
java
1 | static final class NonfairSync extends Sync { |
lock-写锁
java
1 | public void lock() { |
lock-读锁
java
1 | public void lock() { |
unlock-写锁
java
1 | // ReentrantLock一致 |
unlock-读锁
java
1 | public void unlock() { |
await和signal和ReentrantLock一致
Semaphore
- 可限制资源访问数
- 仅适合单机
new
java
1 | public Semaphore(int permits) { |
acquire-非公平
java
1 | // 通过state值来限制访问量, 超过就放入队列park |
acquire-公平
java
1 | public void acquire() throws InterruptedException { |
release-公平-非公平
java
1 | public void release() { |
CountDownLatch
用来进行线程同步协作,等待所有线程完成倒计时
其中构造参数用来初始化等待计数值,await()用来等待计数归零,countDown用来计数减一
只能使用一次,如果需要重复使用需要用 CyclicBarrier
new
java
1 | public CountDownLatch(int count) { |
countDown
释放
java
1 | public void countDown() { |
await
获取锁,失败进入队列
java
1 | public void await() throws InterruptedException { |
CyclicBarrier
- 可重复使用的 CountDownLatch计数
- 当满足多个线程调用await后才能继续往下执行
new
java
1 | public CyclicBarrier(int parties) { |
await
java
1 | public int await() throws InterruptedException, BrokenBarrierException { |
LongAdder
高效率并发累加器,通过cells将操作分解到多个单元,减少竞争,从而增加效率
new
java
1 | public LongAdder() {} |
add
java
1 | // 防止行共享 |
increment
java
1 | public void increment() { |
sum
java
1 | public long sum() { |
decrement
java
1 | public void decrement() { |
reset
java
1 | // 将cells中的所有值和base都设置为0L |
Exchanger
可两个线程之间数据交换, 一个线程会等待另一个线程的数据到达后进行数据交换(exchange方法)
new
java
1 | public Exchanger() { |
exchange
java
1 | public V exchange(V x) throws InterruptedException { |
FutureTask
可用于异步任务, 可用 CompletableFuture 代替
new
java
1 | // 状态值 |
get
java
1 | public V get() throws InterruptedException, ExecutionException { |
run
java
1 | public void run() { |
cancel
java
1 | public boolean cancel(boolean mayInterruptIfRunning) { |
ConcurrentHashMap
高效 + 并发安全的 HashMap
new
java
1 | // 代表移动状态, 由ForwardingNode占位 |
get
java
1 | // 未采用加锁的方式 |
put
java
1 | public V put(K key, V value) { |
initTable
java
1 | private final Node<K,V>[] initTable() { |
casTabAt
java
1 | // 通过一个基本偏移量 + i << ASHIFT 偏移量 = tab中下标为i的值 |
helpTransfer
java
1 | final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) { |
transfer
java
1 | private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) { |
CopyOnWriteArrayList
一种线程安全的集合,它是
List
接口的实现之一。它的主要特点是读操作不需要锁,因此适用于读多写少的场景。每次写操作(添加、删除、更新元素)都会创建一个新的底层数组的副本,这样可以确保读操作不受写操作的干扰,从而实现线程安全。
new
java
1 | final transient ReentrantLock lock = new ReentrantLock(); |
get
java
1 | public E get(int index) { |
set
java
1 | // 通过copy旧值, 然后修改copy的值。从而读写不影响 |
add
java
1 | public boolean add(E e) { |
remove
java
1 | public E remove(int index) { |
subList
java
1 | public List<E> subList(int fromIndex, int toIndex) { |
LinkedBlockingQueue
一个链表阻塞队列
new
java
1 | // 容量 |
poll
java
1 | public E poll() { |
put
java
1 | public void put(E e) throws InterruptedException { |
take
java
1 | public E take() throws InterruptedException { |
offer
java
1 | public boolean offer(E e) { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 🍍Blog!