JUC-Collection-PriorityBlockingQueue
参考文献
Java多线程进阶(三四)—— J.U.C之collections框架:PriorityBlockingQueue
PriorityBlockingQueue
PriorityBlockingQueue,是在JDK1.5时,随着J.U.C包引入的一种阻塞队列,它实现了BlockingQueue接口,底层基于堆实现.
PriorityBlockingQueue是一种无界阻塞队列,它具有以下特点:
元素按照权重大小的顺序出队:与其他阻塞队列不同,PriorityBlockingQueue是一种优先级队列。元素不是按照FIFO(先进先出)的方式出队,而是根据元素的权重来确定优先级,权重较小的元素先出队。
无需指定最大容量:与ArrayBlockingQueue不同,创建PriorityBlockingQueue时无需指定最大容量,它是真正的无界队列。它只受系统内存大小的限制,没有预设的最大容量。
元素必须可比较:由于PriorityBlockingQueue是基于元素权重排序的,因此队列中的元素必须可比较。这意味着元素必须实现Comparable接口,以便进行排序。
插入元 ...
JUC Collection-LinkedBlockingQueue
参考文献
Java多线程进阶(三三)—— J.U.C之collections框架:LinkedBlockingQueue
LinkedBlockingQueue
LinkedBlockingQueue是在JDK1.5时,随着J.U.C包引入的一种阻塞队列,它实现了BlockingQueue接口,底层基于单链表实现.
LinkedBlockingQueue除了底层数据结构(单链表)与ArrayBlockingQueue不同外,另外一个特点就是:它维护了两把锁——takeLock和putLock。
takeLock用于控制出队的并发,putLock用于入队的并发。这也就意味着,同一时刻,只能只有一个线程能执行入队/出队操作,其余入队/出队线程会被阻塞;但是,入队和出队之间可以并发执行,即同一时刻,可以同时有一个线程进行入队,另一个线程进行出队,这样就可以提升吞吐量。
属性
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 ...
JUC Collection-ArrayBlockingQueue
参考文献
JUC集合: BlockingQueue详解
ArrayBlockingQueue(基于数组的阻塞队列)
队列的容量一旦在构造时指定,后续不能改变;
插入元素时,在队尾进行;删除元素时,在队首进行;
队列满时,调用特定方法插入元素会阻塞线程;队列空时,删除元素也会阻塞线程;
支持公平/非公平策略,默认为非公平策略。
公平策略,是指当线程从阻塞到唤醒后,以最初请求的顺序(FIFO)来添加或删除元素;
非公平策略指线程被唤醒后,谁先抢占到锁,谁就能往队列中添加/删除顺序,是随机的。
属性
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable { /** * 内部数组 ...
JUC Collection-BlockingQueue
参考文献
JUC集合: BlockingQueue详解
BlockingQueue
BlockingQueue是Java中的一个接口,用于在多线程环境下实现线程间的安全数据交换.它通常用于生产者-消费者场景,其中一个线程负责向队列中放入对象,另一个线程负责从队列中取出对象.
在这个场景中,生产线程会不断地创建新对象并将其插入到队列中,直到队列达到其容量上限.一旦队列达到临界点,生产线程在尝试插入新对象时会被阻塞.它会一直等待,直到消费线程从队列中取走一个对象.消费线程则会一直从队列中取出对象.如果消费线程尝试从空队列中提取对象,它也会被阻塞,直到生产线程将一个对象放入队列中.
BlockingQueue的实现类有多种,包括ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue等.不同的实现类有着不同的特性和适用场景,但它们都遵循上述的基本原理.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 ...
Java并发编程(十六)-JUC Collections
参考文献
JUC Collections 集合框架
Queue
Blocking Queue阻塞队列
java.util.concurrent.ArrayBlockingQueue:最基础且开发中最常用的阻塞队列,底层采用数组实现的有界队列,初始化需要指定队列的容量.
ArrayBlockingQueue 是如何保证线程安全的呢?它内部是使用了一个重入锁ReentrantLock,并搭配 notEmpty、notFull 两个条件变量Condition来控制并发访问.从队列读取数据时,如果队列为空,那么会阻塞等待,直到队列有数据了才会被唤醒.如果队列已经满了,也同样会进入阻塞状态,直到队列有空闲才会被唤醒.
java.util.concurrent.LinkedBlockingQueue:内部采用的数据结构是链表,队列的长度可以是有界或者无界的.
初始化不需要指定队列长度,默认是Integer.MAX_VALUE.LinkedBlockingQueue 内部使用了takeLock、putLock两个重入锁ReentrantLock,以及notEmpty、notFull两 ...
Java并发编程-原子操作类概览
参考文献
原子操作类
由于变量类型的关系,在J.U.C中提供了12个原子操作的类.这12个类可以分为四大类:
基本类型:
AtomicBoolean: 原子更新布尔类型
AtomicInteger: 原子更新整型
AtomicLong: 原子更新长整型
数组类型:
AtomicIntegerArray: 原子更新整型数组里的元素
AtomicLongArray: 原子更新长整型数组里的元素
AtomicReferenceArray: 原子更新引用类型数组里的元素
引用类型:
AtomicReference: 原子更新引用类型
AtomicReferenceFieldUpdater: 原子更新引用类型里的字段
AtomicMarkableReference: 原子更新带有标记位的引用类型,可以原子更新一个布尔类型的标记位和引用类型.
字段更新:
AtomicIntegerFieldUpdater: 原子更新整型的字段的更新器
AtomicLongFieldUpdater: 原子更新长整型字段的更新器
AotmicStampedReference: 原子 ...
Java并发编程-面试题(一)
参考文献
Java中线程的实现方式?
继承Thread类,重写run方法
实现Runnable接口,重写run方法
实现Callable接口,重写call方法,配合FutureTask
Callable一般用于有返回结果的非阻塞的执行方法
同步非阻塞
线程的状态
NEW
RUNNABLE
READY
RUNNING
WAITING
TIMED_WAITING
BLOCKED
TERMINATED
并发编程的三大特性
原子性
问题存在的原因: 分时复用机制引起
使用synchroinzed和Lock接口实现的锁
使用CAS
有序性
问题存在的原因: 重排序引起
使用volatile
使用synchroinzed和Lock接口实现的锁
Happens-Before
可见性
问题存在的原因: CPU缓存引起
使用volatile
使用synchroinzed和Lock接口实现的锁
使用final
Happens-Before原则
程序次序规则
管程锁定规则
volatile变量规则
线程启动规则
线程终止规则
线程中断规则
对象终结规则
Java锁的分 ...
Java并发编程(十三)-累加器
参考文献
累加器
AtomicLong :这是最基本的累加器,支持单个long类型的原子性操作.适用于低并发场景或单线程环境.
LongAdder :相比于AtomicLong ,LongAdder 在高并发环境中的性能更好,因为它使用了分段锁来避免多个线程同时竞争一个变量的情况.适用于高并发场景下的计数器或统计器.
DoubleAdder :与LongAdder 类似,但支持double类型的原子性操作.适用于需要累加double类型数据的高并发场景.
LongAccumulator :支持任意函数的原子性操作,可以自定义累加函数.适用于需要累加的场景比较复杂,需要自定义累加函数的情况.
DoubleAccumulator :与LongAccumulator 类似,但支持double类型的原子性操作.
这些累加器在多线程环境下都可以保证线程安全,可以用于实现高性能的计数器、统计器等场景.选择哪种累加器要根据具体的场景和需求来确定.
如果需要进行高并发的累加操作,可以选择LongAdder 或DoubleAdder ;
如果需要自定义累加函数,可以选择L ...
Java并发编程-Fork/Join
参考文献
JUC线程池: Fork/Join框架详解
线程池ForkJoinPool简介
Fork/Join
Fork/Join框架是Java并发工具包中的一种可以将一个大任务拆分为很多小任务来异步执行的工具,自JDK1.7引入。
ForkJoinPool是ThreadPoolExecutor线程池的一种补充,是对计算密集型场景的加强
Fork/Join组成
任务对象: ForkJoinTask (包括RecursiveTask、RecursiveAction 和 CountedCompleter)
ForkJoinPool只接收ForkJoinTask 任务(在实际使用中,也可以接收 Runnable/Callable 任务,但在真正运行时,也会把这些任务封装成 ForkJoinTask 类型的任务)
RecursiveTask是ForkJoinTask的子类,是一个可以递归执行的 ForkJoinTask
RecursiveAction 是一个无返回值的 RecursiveTask,CountedCompleter 在任务完成执行后会触发执行一个自定义的钩子函数。
...
Java并发编程-FutureTask
参考文献
JUC线程池: FutureTask详解
FutrueTask
FutureTask为Future提供了基础实现,如获取任务执行结果(get)和取消任务(cancel)等.如果任务尚未完成,获取任务执行结果时将会阻塞.一旦执行结束,任务就不能被重启或取消(除非使用runAndReset执行计算).FutureTask 常用来封装 Callable 和 Runnable,也可以作为一个任务提交到线程池中执行.除了作为一个独立的类之外,此类也提供了一些功能性函数供我们创建自定义 task 类使用.FutureTask 的线程安全由CAS来保证.
Callable接口
123456789public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute ...