ReentrantLock是一个较为常用的锁对象 可重入的互斥锁定 与synchronized 相同的一些基本行为和语义,但功能更强大
Condition类与lock绑定,用newCondition()方法创建,提供了线程之间通信的方式(类似信号量)。
其使用基本与object类的wait,notify,notifyAll相同。
1,用condition.await()替换Object,wait(),调用时该线程阻塞,释放该线程的锁。
2,用condition.signal()替换Object.notify(),用condition.signalAll()替换Object.notifyAll(),唤醒该condition await方法所阻塞的线程
public class LinkedBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable { //链表节点node类结构 static class Node<E> { volatile E item;//volatile,保证了数据的可见性 Node<E> next; Node(E x) { item = x; } } //容量 private final int capacity; //用原子变量,当前元素个数 private final AtomicInteger count = new AtomicInteger(0); //头节点 private transient Node<E> head; //表尾节点 private transient Node<E> last; //获取元素或删除元素时,要加的takeLock锁 private final ReentrantLock takeLock = new ReentrantLock(); //获取元素时若队列为空,线程阻塞,直至notEmpty条件满足(被通知) private final Condition notEmpty = takeLock.newCondition(); //插入元素时 要加putLock锁 private final ReentrantLock putLock = new ReentrantLock(); //插入时,若队列已满,线程阻塞,直至notFull条件满足(被通知) private final Condition notFull = putLock.newCondition(); // 唤醒等待的take操作,插入数据时若插入前链表中无数据,则调用,表示链表不再为空 private void signalNotEmpty() { final ReentrantLock takeLock = this.takeLock; takeLock.lock(); try { notEmpty.signal(); } finally { takeLock.unlock(); } } //唤醒等待插入操作,移除数据时若链表原先已满则调用,表示链表不再满 private void signalNotFull() { final ReentrantLock putLock = this.putLock; putLock.lock(); try { notFull.signal(); } finally { putLock.unlock(); } } // 插入到链表尾部 private void insert(E x) { last = last.next = new Node<E>(x); } //获取并移除头元素 private E extract() { Node<E> first = head.next; head = first; E x = first.item; first.item = null; return x; } //锁住两把锁,在remove,clear等方法中调用 private void fullyLock() { putLock.lock(); takeLock.lock(); } //和fullyLock成对使用 private void fullyUnlock() { takeLock.unlock(); putLock.unlock(); } //默认构造,容量为 Integer.MAX_VALUE public LinkedBlockingQueue() { this(Integer.MAX_VALUE); } //指定容量的构造 public LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node<E>(null); } //指定初始化集合的构造 public LinkedBlockingQueue(Collection<? extends E> c) { this(Integer.MAX_VALUE); for (E e : c) add(e); } //获得大小 public int size() { return count.get(); } //剩余容量 public int remainingCapacity() { return capacity - count.get(); } // 将指定元素插入到此队列的尾部,如已满,阻塞至队列中有元素被移除 public void put(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); int c = -1; final ReentrantLock putLock = this.putLock; final AtomicInteger count = this.count; //加put锁,多个线程不能同时进入 putLock.lockInterruptibly(); try { try { //容量已满,则一直阻塞 while (count.get() == capacity) notFull.await(); } catch (InterruptedException ie) { notFull.signal(); // propagate to a non-interrupted thread throw ie; } //插入 insert(e); c = count.getAndIncrement(); //通知链表未满 if (c + 1 < capacity) notFull.signal(); } finally { //解锁,注意必须在finally里调用,反正各种异常导致没有unlock使线程死锁 putLock.unlock(); } //通知链表非空 if (c == 0) signalNotEmpty(); } // 将指定元素插入到此队列的尾部,如有必要,则等待一定时间以使空间变得可用。 public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); long nanos = unit.toNanos(timeout); int c = -1; final ReentrantLock putLock = this.putLock; final AtomicInteger count = this.count; //加锁 putLock.lockInterruptibly(); try { for (;;) { //未满可插入 if (count.get() < capacity) { insert(e); c = count.getAndIncrement(); //通知未满 if (c + 1 < capacity) notFull.signal(); //跳出循环 break; } //队列已满,未能插入,等待时间是负的,直接返回 if (nanos <= 0) return false; try { //等待一定时间后再次尝试 nanos = notFull.awaitNanos(nanos); } catch (InterruptedException ie) { notFull.signal(); // propagate to a non-interrupted thread throw ie; } } } finally { //解锁 putLock.unlock(); } //通知已插入数据,链表非空 if (c == 0) signalNotEmpty(); return true; } //将指定元素插入到此队列的尾部(如果立即可行且不会超出此队列的容量), 在成功时返回 true,如果此队列已满,则返回 false。 public boolean offer(E e) { if (e == null) throw new NullPointerException(); final AtomicInteger count = this.count; if (count.get() == capacity) return false; int c = -1; final ReentrantLock putLock = this.putLock; putLock.lock(); try { //由于可能在lock被阻塞时其他线程进行了插入操作,需再次判断count if (count.get() < capacity) { insert(e); c = count.getAndIncrement(); //通知未满 if (c + 1 < capacity) notFull.signal(); } } finally { putLock.unlock(); } //通知非空 if (c == 0) signalNotEmpty(); // >0表示已成功插入 return c >= 0; } //获取并移除此队列的头部,若队列为空,则阻塞。 public E take() throws InterruptedException { E x; int c = -1; final AtomicInteger count = this.count; final ReentrantLock takeLock = this.takeLock; //加锁 takeLock.lockInterruptibly(); try { try { //队列为空时阻塞 while (count.get() == 0) notEmpty.await(); } catch (InterruptedException ie) { notEmpty.signal(); // propagate to a non-interrupted thread throw ie; } //获取数据 x = extract(); c = count.getAndDecrement(); //通知非空 if (c > 1) notEmpty.signal(); } finally { takeLock.unlock(); } //通知未满 if (c == capacity) signalNotFull(); return x; } //与offer方法结构基本一致,若队列为空,则阻塞一段时间,一段时间后仍为空,则返回null public E poll(long timeout, TimeUnit unit) throws InterruptedException { E x = null; int c = -1; long nanos = unit.toNanos(timeout); final AtomicInteger count = this.count; final ReentrantLock takeLock = this.takeLock; takeLock.lockInterruptibly(); try { for (;;) { if (count.get() > 0) { x = extract(); c = count.getAndDecrement(); if (c > 1) notEmpty.signal(); break; } if (nanos <= 0) return null; try { nanos = notEmpty.awaitNanos(nanos); } catch (InterruptedException ie) { notEmpty.signal(); // propagate to a non-interrupted thread throw ie; } } } finally { takeLock.unlock(); } if (c == capacity) signalNotFull(); return x; } ////与offer方法结构基本一致 队列为空,不阻塞,直接返回null public E poll() { final AtomicInteger count = this.count; if (count.get() == 0) return null; E x = null; int c = -1; final ReentrantLock takeLock = this.takeLock; takeLock.lock(); try { if (count.get() > 0) { x = extract(); c = count.getAndDecrement(); if (c > 1) notEmpty.signal(); } } finally { takeLock.unlock(); } if (c == capacity) signalNotFull(); return x; } //获取但不移除此队列的头;如果此队列为空,则返回 null。 public E peek() { if (count.get() == 0) return null; final ReentrantLock takeLock = this.takeLock; takeLock.lock(); try { Node<E> first = head.next; if (first == null) return null; else return first.item; } finally { takeLock.unlock(); } } /** * 从此队列移除指定元素的单个实例(如果存在)。 */ public boolean remove(Object o) { if (o == null) return false; boolean removed = false; //同时加锁,此时其他线程不能插入,不能移除 fullyLock(); try { Node<E> trail = head; Node<E> p = head.next; //遍历,获取到该元素 while (p != null) { if (o.equals(p.item)) { removed = true; break; } trail = p; p = p.next; } //删除该元素 if (removed) { p.item = null; trail.next = p.next; if (last == p) last = trail; if (count.getAndDecrement() == capacity) notFull.signalAll(); } } finally { fullyUnlock(); } return removed; } …… }
相关推荐
基于风光负荷不确定性的微电网两阶段鲁棒优化模型:投资与运行成本的综合考虑及CCG算法的Matlab+Yamilp+CPLEX求解方法,考虑风光负荷的不确定性,构建了微电网两阶段鲁棒优化容量配置模型,第一阶段目标函数为微电网投资成本,第二阶段目标函数为微电网的运行成本。 采用CCG算法求解。 包含非线性项的线性化处理。 程序代码matlab+yamilp+CPLEX ,核心关键词: 微电网; 两阶段鲁棒优化; 容量配置模型; CCG算法; 线性化处理; MATLAB; YAMILP; CPLEX 用分号分隔每个关键词的结果为: 微电网; 两阶段鲁棒优化; 容量配置模型; CCG算法; 线性化处理; MATLAB; Yamilp; CPLEX,微电网鲁棒优化模型:两阶段成本最小化与线性化处理
西门子S7-200PLC在Z35摇臂钻床控制系统中的应用与组态王组态设计研究,98西门子S7-200PLC和组态王组态Z35摇臂钻床控制系统组态设计PLC设计 ,西门子S7-200PLC; 组态王组态; 摇臂钻床控制系统; PLC设计,西门子S7-200PLC与组态王Z35摇臂钻床控制系统组态设计
烟花代码编程python满屏-10.排队接水——我直接把水吸过来.py
基于三菱PLC的喷灌控制系统设计及组态画面实现,No.393 三菱PLC组态王组态画面基于PLC的喷灌控制设计灌溉控制 ,基于三菱PLC; 喷灌控制设计; 组态王组态画面; 灌溉控制。,基于三菱PLC的喷灌控制设计:组态王组态画面应用
基于Dijkstra算法的路径规划Matlab代码:读取黑白色地图并实现图像上的路径规划示例,读取黑白色地图,在图片上进行路径规划matlab代码 路径规划算法基于读图识别的Dijkstra算法 随意设置坐标,规划路径 示例如下 ,读取地图; 路径规划算法; Dijkstra算法; 坐标设置; 规划路径,基于Dijkstra算法的Matlab黑白色地图路径规划代码
融合空间特征的债券图表数据文本检测方法研究.pdf
基于粒子群优化与遗传算法的高速列车横向悬挂模糊PID控制技术研究:s函数建模与仿真分析详解文件,基于粒子群 遗传算法的高速列车横向悬挂模糊PID控制-s函数搭建。 赠word详解文件 ,基于粒子群; 遗传算法; 高速列车横向悬挂; 模糊PID控制; s函数搭建,基于遗传算法的高速列车悬挂PID模糊控制的S函数构建方案
一种基于Retinex的非线性彩色图像增强算法.pdf
基于因式分解的逆合成孔径雷达三维成像技术及序列因子分解法研究,逆合成孔径雷达三维成像,因式分解法,序列因子分解法。 此部分只做了因式分解的工作,假设散射点已经准确提取并得到散射点坐标矩阵,利用因式分解恢复目标三维结构 ,逆合成孔径雷达三维成像; 因式分解法; 序列因子分解; 散射点提取; 散射点坐标矩阵; 恢复目标三维结构。,利用因式分解恢复三维结构:逆合成孔径雷达三维成像技术
MATLAB R2021b环境下深度学习驱动的车道线检测算法研究与应用,MATLAB环境下一种基于深度学习的车道线检测方法 算法运行环境为matlab r2021b,执行基于深度学习的车道线检测。 if batch ~= numBatches lastFrameIdx = miniBatchSize*batch; else 压缩包=数据+程序 ,核心关键词如下: MATLAB环境; 深度学习; 车道线检测; 算法运行环境; 批处理; 压缩包 以上关键词用分号分隔为: MATLAB环境; 深度学习; 车道线检测; 算法运行环境r2021b; 批处理(batch~numBatches); 压缩包(数据+程序) 注意:最后一个关键词“压缩包”并不是直接从您提供的信息中提炼出来的,而是根据您提到的“压缩包=数据+程序”这一句推断出来的。如果这不是您想要的核心关键词,请告诉我,我会进行相应的调整。,MATLAB深度学习车道线检测算法压缩包
西门子S7-200PLC在物料自动称量控制系统中的应用:基于称重配料混合程序的组态设计与王设计PLC程序设计,74基西门子S7-200PLC的物料自动称量控制系统称重配料物料混合程序组态设计组态设计组态王设计plc程序设计 ,核心关键词:西门子S7-200PLC;自动称量控制系统;物料混合程序;组态设计;组态王设计;PLC程序设计。,西门子S7-200PLC物料自动称量控制系统称重配料程序组态设计
优化无人机侦查与目标搜索路径规划:对未知区域进行覆盖并精确寻靶的Matlab代码解析与实践指南。,无人机覆盖搜索路径规划 无人机搜索目标路径规划 无人机侦查路径规划 对未知区域进行覆盖搜索,并且寻找目标 matlab代码有详细注释,可快速上手。 ,核心关键词:无人机; 覆盖搜索路径规划; 搜索目标路径规划; 侦查路径规划; 未知区域覆盖搜索; MATLAB代码注释。,**无人机未知区域覆盖搜索及目标路径规划Matlab代码详解**
shp格式,可直接导入arcgis使用
基于博途软件编程的11层电梯控制系统:文档齐全,优质售后保障的智能运行体验,基于PLC的单部11层电梯控制系统,采用博途软件编写提供画面,文档(含接线图,流程图,IO分配表)及优质的后服务。 最终运行效果,详见上方演示视频 ,核心关键词:PLC控制;11层电梯;博途软件;画面编写;文档资料;接线图;流程图;IO分配表;售后服务;演示视频。,"博途软件控制下的11层电梯系统,高效运行效果详见演示视频"
"飞剪追剪程序:PLC与伺服同步控制完整指南,适合新手学习与参考,包含PLC程序、触摸屏程序及CAD电路图纸",飞剪追剪程序plc程序伺服程序 同步控制 适合新手学习参考 包含PLC程序+触摸屏程序+CAD电路图纸。 ,飞剪追剪程序; PLC程序; 伺服程序; 同步控制; 新手学习参考; PLC程序+触摸屏程序; CAD电路图纸,适合新手的飞剪追剪程序全套教程:PLC+伺服同步控制
使用Matlab编程:无迹卡尔曼滤波算法(UKF)的编写及其在电池SOC估计中的应用,噪声系数自适应优化方案的研究。,使用matlab编写m脚本,编写无迹卡尔曼滤波算法(UKF)估计电池SOC,注释清晰。 卡尔曼滤波算法(EKF)锂电池SOC估计,噪声系数自适应 Matlab ,matlab; 无迹卡尔曼滤波算法(UKF); 电池SOC估计; 注释清晰; 噪声系数自适应。,Matlab无迹卡尔曼滤波(UKF)用于电池SOC估计的代码实现
Ansys LS-DYNA多孔延时起爆与重复起爆模拟的完整过程解析,Ansys ls_dyna多孔延时起爆,重复起爆模拟 全过程 ,Ansys;LS_dyna;多孔延时起爆;重复起爆模拟;全过程,Ansys LS-DYNA多孔延时重复起爆模拟全过程
FPGA驱动双目视觉系统:立体匹配、视差图与深度图生成技术的研究与应用,FPGA双目视觉 立体视觉 视差图 深度图 双目立体匹配sgm sgbm tang 20k 高云fpga usb摄像头采集图像 ,FPGA双目视觉;立体视觉;视差图;深度图;双目立体匹配sgm;sgbm;高云FPGA;USB摄像头图像采集。,基于FPGA的双目视觉系统:立体匹配与深度图生成
整个手套大盘的指数图如下.docx
基于AGV全覆盖移动避障的扫地机器人路径规划算法研究:深度优先搜索与随机碰撞对比,AGV全覆盖移动避障路径规划matlab代码 扫地机器人路径规划 第一类算法 全覆盖智能算法 %% 基于深度优先搜索算法的路径规划—扫地机器人移动仿真 % 返回深度优先搜索实现全覆盖的运行次数 % 将栅格模型的每一个栅格看成一个点 % 实际中栅格模型是连续的,在计算机处理时看作离散的 % 将栅格模型抽象为标识矩阵,矩阵对应位置的标记表示栅格对应位置的状态 第二对比算法 %% 随机碰撞的路径规划—扫地机器人移动仿真 % 返回深度优先搜索实现全覆盖的运行次数 % 将栅格模型的每一个栅格看成一个点 % 实际中栅格模型是连续的,在计算机处理时看作离散的 % 将栅格模型抽象为标识矩阵,矩阵对应位置的标记表示栅格对应位置的状态 ,核心关键词: 1. AGV全覆盖移动避障 2. 路径规划 3. Matlab代码 4. 扫地机器人路径规划 5. 第一类算法 6. 全覆盖智能算法 7. 深度优先搜索算法 8. 栅格模型 9. 标识矩阵 10. 随机碰撞的路径规划,"AGV全覆盖避障路径规划:Matlab代码实现与对比"