当前位置: 首页 > news >正文

Java中手动床架一个线程池

原文:Java多线程实战-从零手搓一个简易线程池(一)定义任务等待队列_java等待队列-CSDN博客

package com.thread;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;/*** @program: FlinkTutorial-1.17.0* @description:* @author: gaoyf* @create: 2025-08-03 19:36**/
public class BlockQueue<T> {private static final Logger log = LoggerFactory.getLogger(BlockQueue.class);// 双端队列private Deque<T> deque = new ArrayDeque<>();// 队列的容量private int size;public BlockQueue(int size) {this.size = size;}// ReentrantLock可重入锁来解决这个问题private ReentrantLock lock = new ReentrantLock();// 分别定义两个Condition代表队列满情况的等待室与队列空情况的等待室// 队列空情况的休息室Condition emptyCondition = lock.newCondition();// 队列满情况的休息室Condition fullCondition = lock.newCondition();// 定义阻塞添加任务方法put// 添加任务 阻塞添加public void put(T task) {lock.lock();try {while (size == deque.size()) {try {fullCondition.await();} catch (InterruptedException e) {throw new RuntimeException(e);}}log.debug("task 添加成功 ,{}", task);deque.addLast(task);emptyCondition.signal();} finally {lock.unlock();}}// 这里添加任务会存在两张情况://队列满了:调用fullCondition.await()方法挂起当前生产者线程,也就是让当前生产者线程等待。//队列没满:将任务加入队列中,并调用emptyCondition.signal()通知挂起的消费者。// 编写堵塞拿取任务方法take// 获取任务public T take() {lock.lock();try {while (deque.isEmpty()) {try {emptyCondition.await();} catch (InterruptedException e) {throw new RuntimeException(e);}}T t = deque.removeFirst();fullCondition.signal();log.debug("获取了任务 {}", t);return t;} finally {lock.unlock();}}// 同理,这里拿取任务也会存在两张情况://队列空的:调用emptyCondition.await()方法挂起当前消费者线程,也就是让当前消费者线程等待。//队列存在元素:任务出栈,并返回出栈的任务元素,然后调用fullCondition.signal()通知挂起的生产者。// 以上我们其实我们就完成了一个简单的任务堵塞队列,但是我们会发现,如果这两个方法都是会一直堵塞,显然是不合理的,所以我们这里新增添加和获取任务的超时方法。// 带超时时间的阻塞添加方法offer// 带超时时间阻塞添加public boolean offer(T task, long timeout, TimeUnit timeUnit) {lock.lock();try {long nanos = timeUnit.toNanos(timeout);while (deque.size() == size) {try {if (nanos <= 0) {return false;}log.debug("等待加入任务队列 {} ...", task);nanos = fullCondition.awaitNanos(nanos);} catch (InterruptedException e) {e.printStackTrace();}}log.debug("加入任务队列 {}", task);deque.addLast(task);emptyCondition.signal();return true;} finally {lock.unlock();}}// 我们可以利用fullCondition.awaitNanos来实现超时等待,当超过给定参数时间时,就会被自动唤醒,并且将传入时间-等待时间作为返回值,下一次循环nanos <= 0时,就会判定为本次操作超时失败了// 带超时时间的阻塞获取方法poll// 带超时时间阻塞获取public T poll(long timeout, TimeUnit unit) {// 1.上锁lock.lock();try {long nanos = unit.toNanos(timeout); // 转为毫秒// 2.首先检查队列是否存在元素while (deque.isEmpty()) {try {// 2.1超时判断,返回值是剩余时间if (nanos <= 0) {return null;}// 2.2超时等待log.debug("等待获取任务");nanos = emptyCondition.awaitNanos(nanos);} catch (InterruptedException e) {e.printStackTrace();}}// 3.拿取元素T task = deque.removeFirst();log.info("任务拿取成功:{}", task);// 4.唤醒挂起的生产者fullCondition.signal();return task;} finally {// 释放锁lock.unlock();}}
}

http://www.dtcms.com/a/313516.html

相关文章:

  • 【OD机试题解法笔记】文件缓存系统
  • 第 10 篇:深度学习的“军火库”——CNN、RNN与Transformer,AI如何看懂世界?
  • pod的创建流程
  • [Linux入门] 从 iptables 到 nftables:初学者入门指南
  • 大数据之路:阿里巴巴大数据实践——元数据与计算管理
  • 【分析学】Hilbert 空间的分离性
  • 分布式事务Seata AT模式设计分析篇
  • 41.安卓逆向2-frida hook技术-过firda检测(五)-利用ida分析app的so文件中frida检测函数过检测
  • 关于Manus AI与多语言手写识别的技术
  • Linux驱动学习(六)一些函数
  • 【canvas】
  • 从WebShell 与 ShellCode 免杀技术 打造适合自己的免杀技术链
  • 设计模式 - 组合模式:用树形结构处理对象之间的复杂关系
  • 攻防世界-web-csaw-mfw
  • 【C++】封装,this指针
  • C++高阶笔记第四篇:STL-函数对象
  • 【Leetcode】2106. 摘水果
  • Yakit热加载魔术方法模版插件语法JSRpc进阶调用接口联动
  • 【Bluedroid】btif_av_handle_event 流程源码解析
  • 更换KR100门禁读头&主机
  • UART串口常用库函数(STC8系列)
  • LLM大模型开发-SpringAI:ChatClient、Ollama、Advisor
  • greenfoot主要api
  • 广东省省考备考(第六十五天8.3)——判断推理:图形推理(数量规律题目总结)
  • 使用C++实现日志(3)
  • sqli-labs:Less-23关卡详细解析
  • C的数据类型与变量
  • 2025 Java开发真实试题-阿里面试题分析
  • C语言与数据结构:从基础到实战
  • 机器学习——过采样(OverSampling),解决类别不平衡问题,案例:逻辑回归 信用卡欺诈检测