多线程系列3-JUC阻塞队列方法

JUC面试:

Java JUC是Java Util Concurrent的缩写,指的是java.util.concurrent工具包,这是Java中处理并发编程的核心库。里面的很多功能都是基于ReetrantLock来实现的。比如

ArrayBlockingQueue、
SynchronousQueue、
LinkedBlockingQueue、
DelayQueue、
PriorityBlockingQueue的一些组件。
ReetrantLock是怎么实现的呢,他是用AQS提供的方式去实现的。它是一个抽象方法:
AbstractQueuedSynchronizer,里面提供了实现锁的方法。
里面几个关键属性:
java.util.concurrent.locks.AbstractQueuedSynchronizer#state
head节点
tail节点
是一个双向链表。

JUC

JUC基本概念

Java JUC是Java Util Concurrent的缩写,指的是java.util.concurrent工具包,这是Java中处理并发编程的核心库。

 

1、通用offer方法
当是put时,如果此时队列里的数据为0,则有可能之前有take操作被阻塞,所以需要唤醒读锁里面的await()操作,反之:
当是poll时,如果此时队列里的数据为满,则有可能之前有put操作被阻塞,所以需要唤醒写锁里面的await()操作
 

 LinkedBlockingQueue 链表有双锁,put和take锁。因为有哨兵节点,head = last = node。操作的都是node.next几点,所以读和写不影响,可以并行。

java.util.concurrent.ArrayBlockingQueue 

 

java.util.concurrent.PriorityBlockingQueue

PriorityBlockingQueue它会保证第一个数据是最小的,叫最小堆嘛。

 

 基于数组实现的方式:

 

 

 

 

 

 

程序关键代码实现:递归比较最小,挪到最顶点,堆顶数据最小

 

 

 

 
java.util.concurrent.ArrayBlockingQueue  基于数组的,取和放是同一把锁
java.util.concurrent.LinkedBlockingQueue 基于链表的,取数据和放数据是两把锁(并发高)
java.util.concurrent.DelayQueue 延迟队列,基于PriorityQueue,无界队列
java.util.concurrent.PriorityBlockingQueue 优先级队列, 存还是用的数组,基于二叉堆(满二叉树,小顶堆),输出是有序的,无界队列
SynchronousQueue 等待生产者和消费者来配对

 

 

 

 

 SynchronousQueue 中的 transfer()流程图:

stack操作的是head,因为是先进后出,来了数据就往下面压

queue操作的是tail,因为是先进先出,来了数据就要下面接

----------------------------------------------

对象属性如何cas,对象属性如何cas,对象属性如何cas,对象属性如何cas,对象属性如何cas,对象属性如何cas,

private static final long tailOffset;

UNSAFE = sun.misc.Unsafe.getUnsafe();

Class<?> k = TransferQueue.class;

tailOffset= UNSAFE.objectFieldOffset (k.getDeclaredField("tail"))

这段代码的意思是,获取long类型的 内存key值,用于cpu 做cas操作

TransferQueue 有属性tail,假如我要对这个tail做cas替换操作,那么就需要用到tailOffset

UNSAFE.compareAndSwapObject(this, tailOffset, t, nt);

这里的this指的是当前线程,tailOffset cas操作锁需要的long类型key值,被替换的对象,nt将要设置的值

 

 

 

posted on 2025-05-05 00:01  Hi Martin  阅读(19)  评论(0)    收藏  举报