目录

单例模式

饿汉模式<代码>

懒汉模式<代码>

阻塞队列

阻塞队列概念

阻塞队列解决的问题

阻塞队列工作原理

阻塞队列的优/缺点

优点

缺点

模拟实现阻塞队列<代码>

线程池

线程池概念

线程池解决的问题

线程池参数

四种拒绝策略

线程池工作流程

模拟实现线程池<代码>

定时器

模拟实现定时器<代码>


单例模式

单例设计模式:确保一个类只有一个实例,且单例实例应该为static静态变量,保证全局唯一

单例模式实现方式:

饿汉模式<代码>

class Pattern {private static Pattern instance = new Pattern();private Pattern() {// 设置为私有,目的是外部不能初始化}public static Pattern getInstance() {return instance;}
}
public class SinglePatternOne {public static void main(String[] args) {Pattern instance1 = Pattern.getInstance();Pattern instance2 = Pattern.getInstance();System.out.println(instance2 == instance1);}}

懒汉模式<代码>

class LazyPattern {private volatile static LazyPattern instance;private static Object locker = new Object();private LazyPattern() {// 设置为私有,目的是外部不能初始化}public static LazyPattern getInstance() {if(instance == null) { // 只有第一次调用这个方法才加锁,之后调用就不用再进行加锁synchronized (locker) { // 达到原子性效果if(instance == null) {instance = new LazyPattern();/*** new操作的指令* 1:内存分配* 2:初始化零值* 3:执行构造函数* 正常顺序:1-》2-》3* 但是编译器优化机制,会导致指令重排序,编程 1-》3-》2* 加上volatile关键字,解决编译器优化问题(内存可见性、指令重排序)*/}}}return instance;}
}
public class SinglePatternTwo {public static void main(String[] args) {LazyPattern instance1 = LazyPattern.getInstance();LazyPattern instance2 = LazyPattern.getInstance();System.out.println(instance1 == instance2);}
}

阻塞队列

阻塞队列概念

阻塞队列:是线程安全的队列,是多线程编程中生产者-消费者模型的核心组件。支持队列空时阻塞获取操作,队列满时阻塞插入操作

阻塞队列解决的问题

阻塞队列:协调多个线程之间的工作,主要目的是减少锁竞争(锁竞争:多个线程竞争同一个锁。就是在线程1获取到locker还未释放,线程2就去获取locker,线程2就会阻塞)

阻塞队列工作原理

put(element)方法:插入元素,具有阻塞功能,队列满时进行阻塞

take()方法:移除并返回头部元素,具有阻塞功能,队列空时进行阻塞

阻塞队列中,只有这两个方法具有阻塞功能

阻塞队列的优/缺点

优点

减少资源竞争,提高效率

模块之间能更好的“解耦合”

可以做到削峰填谷(如果资源不够用,服务器就挂了)

缺点

系统结构复杂,维护高

引入队列层数太多,就会增加网络开销

模拟实现阻塞队列<代码>

class Queue {private int[] queue = null;private int head;private int tail;private int size;private Object locker = new Object();public Queue(int capacity) {this.queue = new int[capacity];}public void put(int element) throws InterruptedException {synchronized (locker) {while (size >= queue.length) {locker.wait(); // 队列满时,进行阻塞等待}queue[tail] = element;tail++;if(tail >= queue.length) {tail = 0;}size++;locker.notify();}}public int take() throws InterruptedException {synchronized (locker) {while (size < queue.length) {locker.wait(); // 队列为空时,进行阻塞}int result = head;head++;if(head >= queue.length) {head = 0;}size--;locker.notify();return result;}}
}public class MyBlockingQueue {public static void main(String[] args) {Queue queue = new Queue(10);Thread thread1 = new Thread(() -> {int i = 0;while (i != 400) {try {queue.put(i);System.out.println("存入队列:" + i);i++;} catch (InterruptedException e) {throw new RuntimeException(e);}if(i == 20) {try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}});Thread thread2 = new Thread(() -> {int result = 0;while (true) {try {result = queue.take();System.out.println(result);} catch (InterruptedException e) {throw new RuntimeException(e);}if(result == 40) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}});thread1.start();thread2.start();}
}

线程池

线程池概念

线程池:是一种管理和复用线程的机制,通过预先创建一组线程并统一管理任务执行

线程池解决的问题

  1. 避免频繁创建/销毁线程。降低资源消耗
  2. 任务到达时,直接使用空闲线程,无需等待线程创建。提高响应速度
  3. 防止无限制创建线程导致系统崩溃。管控并发数量
  4. 支持任务排队、拒绝策略、监控功能等。统一任务管理

线程池参数

1:corePoolSize 核心线程数目

2:maximumPoolSize 最大线程数目(最大线程数=核心线程数+临时线程数)

3:keepAliveTime 临时线程在终止前等待新任务的最长时间

4:unit 是keepAliveTime的时间单位(时、分、秒、毫秒)

5:workQueue 任务队列,队列仅保存由execute方法提交的可运行任务

6:threadFactory 线程工厂,执行器创建新线程时使用的工厂

7:handler 拒绝策略,达到线程边界或队列容量时使用拒绝策略

四种拒绝策略

  1. AbortPolicy 中止策略,总是抛出RejectedExecutionException异常
  2. CallerRunsPolicy 提交任务的线程自己执行任务
  3. DiscardOldestPolicy 丢弃队列中最老的一个任务,然后重新尝试提交当前任务
  4. DiscardPolicy 丢弃队列中最新的一个任务,不抛异常不通知

线程池工作流程

模拟实现线程池<代码>

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;class MyThreadPool {private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();// 安全的阻塞队列,用于存放任务public void myThreadPool(int threads) {for (int i = 0; i < threads; i++) { // 创建线程,用于取任务,并执行任务Thread thread = new Thread(() -> {try {Runnable task  = queue.take(); // 取任务task.run(); // 执行任务} catch (InterruptedException e) {throw new RuntimeException(e);}});thread.start();}}public void submit(Runnable task) throws InterruptedException {queue.put(task); // 上传任务}
}
public class MyFixedThreadPool {// 只有核心线程数public static void main(String[] args) throws InterruptedException {MyThreadPool threadPool = new MyThreadPool();threadPool.myThreadPool(10);
//        threadPool.submit(new Runnable() { // 这样只提交了一个任务
//            @Override
//            public void run() {
//                for (int i = 0; i < 20; i++) {
//                    System.out.println("任务:" + i);
//                }
//            }
//        });for (int i = 0; i < 30; i++) { // 这样就是多线程抢占式执行int id = i;threadPool.submit(new Runnable() {@Overridepublic void run() {System.out.println("任务:" + id);}});}}
}

定时器

定时器:用于在指定时间或周期性地执行任务的工具。能够同时管理多个任务,有一定数据结构来组织这些任务。广泛用于任务调度、超时控制等

模拟实现定时器<代码>

注意:

两个线程操作一个队列,可能引发线程安全问题,所以需要加锁(synchronied)

当队列为空时,线程应该阻塞等待;当任务还没到执行时间时,线程也要阻塞等待

class TimerTask implements Comparable<TimerTask> {private Runnable task;private long time; // 任务执行时间public TimerTask(Runnable task, long delay) {this.task = task;this.time = System.currentTimeMillis() + delay;}public Runnable getTask() {return task;}public long getTime() {return time;}// 因为要将类放到优先级队列当中,所以需要给类指定比较规则(1:实现Comparable接口 / 2:自己写一个类,实现Comparator)@Overridepublic int compareTo(TimerTask o) {return (int)(this.time-o.time);}
}
class MyTimer {private PriorityQueue<TimerTask> queue = new PriorityQueue<>(); // 优先级队列,用于存放任务private Object locker = new Object();/*** submit(xx)方法存放任务 和 此处取任务,执行任务,删除任务 -》是两个线程同时修改一个队列* 两个线程同时修改一个队列,可能会引发线程安全问题-》所以需要加锁(synchronied)*/public MyTimer() { // 创建线程,取出任务,执行任务(到时间执行),删除任务Thread thread = new Thread(() -> {while (true) {synchronized (locker) {if (queue.isEmpty()) {try {locker.wait(); // 当队列为空时,就进行阻塞等待。队列中有任务时,就执行下面操作} catch (InterruptedException e) {throw new RuntimeException(e);}}TimerTask timerTask = queue.peek(); // 取出队首任务long curTime = System.currentTimeMillis();if (curTime < timerTask.getTime()) {try {locker.wait(timerTask.getTime() - curTime);} catch (InterruptedException e) {throw new RuntimeException(e);}} else {timerTask.getTask().run(); // 执行任务(到时间执行任务)queue.poll(); // 删除队首任务}}}});thread.start();}public void submit(Runnable task, long delay) {synchronized (locker) {queue.offer(new TimerTask(task, delay)); // 任务存入队列locker.notify();}}
}public class Timer {public static void main(String[] args) {MyTimer myTimer = new MyTimer();myTimer.submit(new Runnable() {@Overridepublic void run() {System.out.println("4s后执行");}}, 4000);myTimer.submit(new Runnable() {@Overridepublic void run() {System.out.println("5s后执行");}}, 5000);myTimer.submit(new Runnable() {@Overridepublic void run() {System.out.println("2s后执行");}}, 2000);System.out.println("启动程序");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912739.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912739.shtml
英文地址,请注明出处:http://en.pswp.cn/news/912739.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis初识第七期---ZSet的命令和应用场景

ZSet相较于Set来说&#xff0c;它又是有序的&#xff0c;这个有序指的就是我们通常意义上的有序了&#xff0c;ZSet内部中是按照升序来排序的。 排序规则&#xff1a;ZSet相较于Set来说&#xff0c;它内部引入了一个新的属性&#xff1a;分数&#xff08;Score&#xff09;&am…

Wps开放平台v5升级v7上传实体文件踩坑(Java使用restTemplate)

背景&#xff1a; 最近接到一个老项目需求&#xff0c;之前开发的WPS开放平台文件&#xff08;商密集成&#xff09;预览功能因为升级需要重新对接api&#xff0c;新的上传文件接口踩坑特意记录一下。 这里出问题的是第二步&#xff0c;请求文件上传信息 踩坑代码 调用后403 p…

啥时候上RAG?啥时候上微调?丨实战笔记

哈喽&#xff0c;大家好&#x1f44f; 我是阿星&#xff01; 现在很多AI科普文章都会提到微调&#xff0c;RAG。 但是没有实战的过的同学可能会问&#x1f914;—— 啥时候用RAG&#xff1f;啥时候用微调呢&#xff1f;有啥区别&#xff1f;不都是让模型增加知识面的吗&…

RabbitMQ-基础篇

前言&#xff1a; 今天开始学RabbitMQ,还是跟着黑马的课程。 今日所学&#xff1a; RabbitMQ介绍RabbitMQ入门Java客户端中的MQ 1.RabbitMQ介绍 1.1 什么是RabbitMQ RabbitMQ 是一个开源的消息代理软件&#xff08;消息队列中间件&#xff09;&#xff0c;实现了高级消息…

docker-compose配置redis哨兵详细步骤和配置文件

docker-compose配置redis哨兵详细步骤和配置文件 目录结构调整 redis-cluster/ ├── config/ │ ├── master.conf # 主节点配置 │ ├── slave1.conf # 从节点1配置 │ ├── slave2.conf # 从节点2配置 │ ├── sentinel1.…

多模态大语言模型arxiv论文略读(146)

Exploring Response Uncertainty in MLLMs: An Empirical Evaluation under Misleading Scenarios ➡️ 论文标题&#xff1a;Exploring Response Uncertainty in MLLMs: An Empirical Evaluation under Misleading Scenarios ➡️ 论文作者&#xff1a;Yunkai Dang, Mengxi G…

【教程】Linux中限制用户可以使用的GPU数量 | 附脚本

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 背景说明 设置方法 管理脚本 进阶限制 恢复默认组 注意事项 背景说明 比较简单的方式是使用group来管理权限&#xff0c;这种方式能限制哪些…

90.xilinx复位低电平(一般使用低电平复位)

Xilinx FPGA 中的寄存器&#xff08;Flip-Flop&#xff09;**确实支持异步复位**&#xff0c;但具体实现方式取决于你使用的设计方法&#xff08;HDL 代码风格或原语实例化&#xff09;。以下是详细说明&#xff1a; --- ### 1. **Xilinx 寄存器的复位特性** - **同步复位…

NVMe高速传输之摆脱XDMA设计10: DMA 控制单元设计

DMA 控制单元负责控制 DMA 传输事务&#xff0c; 该单元承担了 DMA 事务到 NVMe 事务的转换任务&#xff0c; 使用户对数据传输事务的控制更加简单快捷。 DMA 控制功能由 DMA寄存器组实现。 DMA 寄存器组包含 DMA 操作寄存器、 DMA 长度寄存器、 DMA 源目的地址寄存器和 DMA 状…

如何设置电脑定时休眠?操作指南详解

长时间运行电脑会导致硬件过热&#xff0c;缩短其使用寿命。定时关机有助于让硬件得到休息&#xff0c;降低因长时间高负荷工作导致损坏的风险。 它的界面简洁直观&#xff0c;功能却十分实用&#xff0c;涵盖了定时关机、重启、注销、休眠、待机以及锁定等多种操作。 以设置“…

LeetCode[617]合并二叉树

思路&#xff1a; 我们合并左右子树&#xff0c;在递归左右子树的时候&#xff0c;一定要保证左右子树不为空&#xff0c;如果左子树为空&#xff0c;那么直接返回右子树就行了&#xff0c;即使右子树为空。如果右子树为空那么直接返回左子树就行了&#xff0c;这样判断完就正常…

Redis 常用五大数据类型

1、Redis 关键字&#xff08;Key&#xff09; keys * 查看当前库所有keyexists [key] 判断某个key是否存在type [key] 查看当前key的数据类型del [key] 删除指定的key数据unlink [key] 根据value选择非阻塞删除&#xff0c;仅将keys从keyspace元数据中删除&#xff0c;真正的删…

大语言模型(LLM)专业术语汇总

1. 训练与部署 1.1 预训练 专业&#xff1a;在海量无标注文本&#xff08;如Common Crawl、Wikipedia&#xff09;上通过自监督学习训练基础语言模型&#xff0c;学习通用语言表征&#xff08;如GPT-3训练数据达45TB&#xff09;。通俗&#xff1a;AI的“通识教育阶段”&…

【Java Swing 图形界面编程】JList 列表组件 ① ( JList 组件简介 | 核心作用 | 关键特性 | 基础用法示例 )

文章目录 一、JList 组件简介1、JList 概念简介2、JList 核心作用3、JList 关键特性 二、JList 组件基础用法示例1、使用 String 数组构建列表项2、使用 Vector 集合构建列表项3、使用 DefaultListModel 构建列表项 一、JList 组件简介 1、JList 概念简介 基本概念 : JList 组件…

【小技巧】Python+PyCharm IDE 配置解释器出错,环境配置不完整或不兼容。(小智AI、MCP、聚合数据、实时新闻查询、NBA赛事查询)

报错信息如下&#xff1a; [unsupported] Python 3.1 (mcp-calculator-main) (3) C:\Users(xsshu\AppData\Local\Programs\Python\Python313\python.exe [unsupported] Python 3.1 C:\Users\xsshu\AppData\Local\Programs\Python\Python311\python.exe 这条输出显示了两个 Pyth…

Ragflow 前后端登录逻辑

前端登录逻辑 路由配置&#xff1a; /login 路由指向 /pages/login 组件。登录表单使用 Ant Design 的 Form, Input, 和 Button 组件。 登录表单处理&#xff1a; 使用 useLogin钩子来处理登录请求。密码通过 RSA 加密后再发送到服务器。成功登录后导航至 /knowledge 页面。 …

基于图神经网络的ALS候选药物预测模型设计与实现

基于图神经网络的ALS候选药物预测模型设计与实现 一、任务背景与意义 肌萎缩侧索硬化症(ALS)是一种致命的神经退行性疾病,目前尚无有效治愈方法。传统药物发现流程耗时长、成本高,而人工智能技术为加速药物发现提供了新途径。本文设计并实现了一个基于图神经网络(GNN)的…

运维打铁: 数据加密与备份恢复策略制定

文章目录 思维导图一、数据加密1. 加密算法选择AES 加密示例&#xff08;Python&#xff09;RSA 加密示例&#xff08;Python&#xff09; 2. 密钥管理3. 加密范围 二、数据备份1. 备份类型全量备份增量备份差异备份 2. 备份频率3. 备份存储位置 三、数据恢复1. 恢复测试2. 恢复…

AIbase MCP服务库上线:集成服务器、客户端、案例教程等服务

在当今数字化时代&#xff0c;人工智能技术正以前所未有的速度发展&#xff0c;深刻地改变着我们的生活和工作方式。而要充分发挥AI的强大能力&#xff0c;离不开高效的工具和服务支持。今天&#xff0c;就让我们来了解一下一个专注于MCP&#xff08;Model Context Protocol&am…

QGIS+CesiumIon

前言 QGIS 3.44中&#xff0c;新增了3D 场景新增地球视图模式&#xff0c;通过Cesium ion插件&#xff0c;支持谷歌全球倾斜模型的加载显示。 目录 1 CesiumIon插件安装 2 加载谷歌全球倾斜模型 1、CesiumIon插件安装 点击菜单【Plugins】->【Manage and Install Plugins】…