线程池相关详解

1.线程池的核心参数

线程池核心参数主要参考ThreadPoolExecutor这个类的7个参数的构造函数:

  • corePoolSize核心线程数目

  • maximumPoolSize最大线程数目=(核心线程+救急线程的最大数目)

  • keepAliveTime生存时间:救急线程的生存时间,生存时间内没有新任务,此线程资源会释放

  • unit时间单位:救急线程的生存时间单位,如秒、毫秒等

  • workQueue当没有空闲核心线程时,新来任务会加入到此队队列里,队列满会创建救急线程执行任务

  • threadFactory线程工厂:可以定制线程对象的创建,如设置线程名字、是否守护线程等

  • handler拒绝策略:当所有线程都在繁忙,workQueue也放满时,会触发拒绝策略

工作流程:

  1. 任务在提交的时候,首先判断核心线程数是否已满,如果没有满则直接添加到工作线程执行。

  2. 如果核心线程满了,则判断阻塞队列是否已满,如果没有满,当前任务存储阻塞队列。

  3. 如果阻塞队列也满了,则判断线程数是否小于最大线程数,如果满足条件,则使用临时线程执行任务。【如果核心或临时线程执行完成任务后会检查阻塞队列中是否有需要执行的线程,如果有,则使用非核心线程执行任务】

  4. 如果所有线程都忙着(核心线程+临时线程)则走拒绝策略。

拒绝策略:

  • AbortPolicy:直接抛出异常,默认策略

  • CallerRunPolicy:用调用者所在的线程来执行任务

  • DiscardOldestPolicy:丢弃阻塞队列中靠前的任务,并执行当前任务

  • DiscardPolicy:直接丢弃任务

2.线程池常见的阻塞队列

常见的有4个,最多用的是ArrayBlockingQueue和LinkedBlockingQueue

  1. ArrayBlockingQueue:基于数组结构的有界阻塞队列FIFO

  2. LinkedBlockingQueue:基于链表结构的有界阻塞队列FIFO

  3. DelayedWorkQueue:是一个优先级队列,可以保证每次出队的任务都是当前队列中执行时间最靠前的

  4. SynchronousQueue:不存储元素的阻塞队列,每个插入操作都必须等待一个移出操作

ArrayBlockingQueue和LinkedBlockingQueue的区别:

左边是LinkedBlockingQueue加锁的方式,右边是ArrayBlockingQueue加锁的方

  • LinkedBlockingQueue读和写各有一把锁,性能相对较好

  • ArrayBlockingQueue只有一把锁,读和写公用,性能相对于

  • LinkedBlockingQueue差一些

3.如何确定核心线程数

设置核心线程数之前,需要熟悉一些执行线程池任务的类型:

  • IO密集型任务:文件读写、DB读写、网络请求

    推荐:核心线程数大小设置为2N+1(N为CPU数)

  • CPU密集型任务:计算型代码、Bitmap转换、Gson转换等

推荐:核心线程数大小设置为N+1

① 高并发、任务执行时间短 -->( CPU核数+1 ),减少线程上下文的切换

② 并发不高、任务执行时间长

IO密集型的任务 --> (CPU核数 * 2 + 1)

计算密集型任务 --> ( CPU核数+1 )③ 并发高、业务执行时间长,解决这种类型任务的关键不在于线程池而在于整

体架构的设计,看看这些业务里面某些数据是否能做缓存是第一步,增加服务器

是第二步,至于线程池的设置,设置参考(2)

4.线程池的种类

  • 创建使用固定线程数的线程池

  • 单线程化的线程池

  • 可缓存线程池

  • 提供了“延迟”和“周期执行”功能的ThreadPoolExecutor

1.创建使用固定线程数的线程池

  • 核心线程数与最大线程数一样,没有救急线程

  • 阻塞队列是LinkedBlockingQueue,最大容量为Integer.MAX_VALUE

  • 场景:适用于任务量已知,相对耗时的任务

2.单线程化的线程池,它只会用唯一的工作线程来执行任 务,保证所有任务按

照指定顺序(FIFO)执行

  • 核心线程数和最大线程数都是1

  • 阻塞队列是LinkedBlockingQueue,最大容量为Integer.MAX_VALUE

  • 适用场景:适用于按照顺序执行的任务

3.可缓存线程池

  • 核心线程数为0

  • 最大线程数是Integer.MAX_VALUE

  • 阻塞队列为SynchronousQueue:不存储元素的阻塞队列,每个插入操作都必须等待一个移出操作。

  • 适用场景:适合任务数比较密集,但每个任务执行时间较短的情况

4.提供了“延迟”和“周期执行”功能的ThreadPoolExecutor

适用场景:有定时和延迟执行的任务

5.为什么不建议用Executors创建线程池

6.CountDownLatch

CountDownLatch(闭锁/倒计时锁)用来进行线程同步协作,等待所有线程完成倒计时(一个或者多个线程,等待其他多个线程完成某件事情之后才能执行)

  • 其中构造参数用来初始化等待计数值

  • await() 用来等待计数归零

  • countDown() 用来让计数减一

7.控制某个方法允许并发访问线程的数量

Semaphore [ˈsɛməˌfɔr] 信号量,是JUC包下的一个工具类,我们可以通过其限制

执行的线程数量,达到限流的效果当一个线程执行时先通过其方法进行获取许可操作,获取到许可的线程继续执行业务逻辑,当线程执行完成后进行释放许可操作,未获取达到许可的线程进行等待或者直接结束。

Semaphore两个重要的方法

lsemaphore.acquire(): 请求一个信号量,这时候的信号量个数-1(一旦没有可使用的信号量,也即信号量个数变为负数时,再次请求的时候就会阻塞,直到其他线程释放了信号量)

lsemaphore.release():释放一个信号量,此时信号量个数+1

8.谈谈对ThreadLocal的理解

ThreadLocal是多线程中对于解决线程安全的一个操作类,它会为每个线程都分配一个独立的线程副本从而解决了变量并发访问冲突的问题。ThreadLocal 同时实现了线程内的资源共享。

ThreadLocal基本使用:

  • set(value) 设置值

  • get() 获取值

  • remove() 清除值

实现原理:

ThreadLocal本质来说就是一个线程内部存储类,从而让多个线程只操作自己内部的值,从而实现线程数据隔离。在ThreadLocal中有一个内部类叫做ThreadLocalMap,类似于HashMap。ThreadLocalMap中有一个属性table数组,这个是真正存储数据的位置。

ThreadLocal内存泄漏:

Java对象中的四种引用类型:强引用、软引用、弱引用、虚引用

  • 强引用:最为普通的引用方式,表示一个对象处于有用且必须的状态,如果一个对象具有强引用,则GC并不会回收它。即便堆中内存不足了,宁可出现OOM,也不会对其进行回收

  • 弱引用:表示一个对象处于可能有用且非必须的状态。在GC线程扫描内存区域时,一旦发现弱引用,就会回收到弱引用相关联的对象。对于弱引用的回收,无关内存区域是否足够,一旦发现则会被回收

每一个Thread维护一个ThreadLocalMap,在ThreadLocalMap中的Entry对象继承了WeakReference。其中key为使用弱引用的ThreadLocal实例,value为线程变量的副本

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

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

相关文章

【Linux中vim系列】如何在vim中检索字符串

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

1.2 编译型语言和解释型语言的区别

编译型语言和解释型语言的区别 通过高级语言编写的源码,我们能够轻松理解,但对于计算机来说,它只认识二进制指令,源码就是天书,根本无法识别。源码要想执行,必须先转换成二进制指令。 所谓二进制指令&…

elment-ui el-tabs组件 每次点击后 created方法都会执行2次

先看错误的 日志打印: 错误的代码如下: 正确的日志打印: 正确的代码如下: 前言: 在element-ui的tabs组件中,我们发现每次切换页面,所有的子组件都会重新渲染一次。当子页面需要发送数据请求并且子页面过多时,这样会过多的占用网络资源。这里我们可以使用 v-if 来进行…

Oh My Bug || PHPmyAdmin导入csv文件时,502报错

解决: 在宝塔面板文件配置中加入一下代码 location / { proxy_pass http://localhost:888; } location /backend-api { rewrite ^/backend-api(.*)$ $1 break; proxy_pass http://你的ip地址; }

判断出栈顺序是否满足入栈顺序

在学习数据结构的过程中,使用代码实现算法有利于加深理解 下面思路过程以及代码 0.先给出各个变量名字以及作用 1.函数 //match是具体的匹配函数;input是输入的顺序;output是输出的顺序 void match(string& input, string& output); 2.函数内部…

Android 设置相关页面

Android 设置相关页面 本文主要记录下android 中跳转设置相关页面的一些action. 在android 中,我们一般使用intent指定的action来跳转相关设置页面. 1: WLAN Action 设置为Settings.ACTION_WIFI_SETTINGS ,用户可以跳转wifi设置页面. Intent intent new Intent(Settings.…

基于python+vue发艺美发店管理系统flask-django-php-nodejs

目 录 摘 要 I Abstract II 1 绪 论 1 1.1 研究背景 1 1.2 研究意义 2 1.3 主要内容 2 2系统相关技术概述 4 2.1开发工具 4 2.2 python语言简介 4 2.4 django框架介绍 5 2.5 MySQL数据库技术简介 6 3 发艺美发店管理系统的设计 7 3.1系统可行性分析 7 3.1.1技术可行性 8 3.1.2…

Service Mesh 概述

🔍 Service Mesh 概述: Service Mesh 是一个专门使服务与服务之间的通信变得安全、快速和可靠的基础设施。对于构建云原生应用的人来说,Service Mesh 是必不可少的。 🧩 Service Mesh 的定义: Service Mesh 是专注于处理服务之间通信的服务…

Linux系统及操作 (09)

Linux系统及操作 (08) 搭建理想环境-----------母版机器 构建YUM仓库 CD光盘安装(注意,虚拟机有时候吃光盘) **[ mount ]**临时挂载CD光盘, 挂载到新创建目录 [ /mydvd ] [ /etc/yum.repos.d ] 清理原有yum文件,并创建新的yum文…

出现nginx error 问题

报错: Something has triggered an error on your website. This is the default error page for nginx that is distributed with Fedora. It is located /usr/share/nginx/html/50x.html You should customize this error page for your own site or edit the er…

使用springboot和vue3以及EasyExcel做导出数据(复用)

Override public void exportData(HttpServletResponse response) {try {// 设置响应结果类型 response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没…

使用docker搭建faiss向量数据库

为了不污染服务器环境,保证程序运行时有更好的隔离性,领导要求基于容器运行程序。 一、准备工作 1、创建文件夹faiss 该文件夹有用于存放faiss相关的文件及脚本 mkdir ~/faiss 2、创建data文件夹 cd ~/faiss mkdir data 这个文件夹用于volume&#xf…

【史上最全面arduino esp32教程】SPI层次结构SPI协议与SPI控制器结构

文章目录 前言一、SPI 程序层次1.1 硬件原理图1.2 硬件框图1.3 软件层次 二、SPI协议2.1 硬件连线2.2 如何访问SPI设备2.3 SPI 框图 总结 前言 欢迎阅读本篇文章,将为您介绍Arduino ESP32上的SPI通信协议。SPI(Serial Peripheral Interface)…

鸿蒙开发案例:【图像加载缓存库ImageKnife】

专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单。 简介 OpenHarmony的自研版本: 支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存。支持磁盘缓存,对于下载图片会保存一份至磁盘当…

新材料正在加速金属3D打印的应用步伐

在金属3D打印领域,材料性能是影响工件综合表现的关键因素,如强度、硬度、耐腐蚀性、抛光性能以及导热性能等,都与材料息息相关,好的材料是推动金属3D打印向更多领域应用的基础。 在这一背景下,上海毅速新材料推出的多款…

JavaScript对象修饰教程

在JavaScript中,对象修饰是一种常见的编程模式,用于动态地向对象添加新的功能或修改现有功能,同时保持对象的原始结构不变。对象修饰可以帮助我们实现代码的复用、扩展和维护,让代码更加灵活和可扩展。本文将深入探讨JavaScript对…

递增四元组

解法: 首先都可以想到dp[i]:第i个元素结尾的递增四元组有dp[i]个 然后发现有一组数据:2,3,6,1,5,8。会出现6结尾和5结尾的递增三元组,也就是未来的决策受过去影响,专业的说就是有后效性。需要强化约束条件&#xff0…

vue3+threejs新手从零开发卡牌游戏(三):尝试在场景中绘制一张卡牌

首先我们思考下,一张最简单的卡牌有哪些东西构成:卡牌样式和卡牌数据。一张卡牌有正面和背面,有名称、属性、种族、攻击力等数据,我们先不考虑数据,先尝试在场景中绘制一张卡牌出来。 一、寻找卡牌素材 为了简单我直…

Streampark 入门到生产实践

Streampark 入门到生产实践 1.StreamPark初探1.1 什么是StreamPark1.2 Features1.3 架构2.环境安装要求如何插入一段漂亮的代码片3.安装apache-streampark 最新版4. 使用教程4.1配置Flink_home4.2 git 拉取项目和构建项目4.3 企业微信告警4.4 相关参数配置4.5 相关参数配置yarn…

变老特效怎么弄?分享3个软件体验!

变老特效怎么弄?分享3个软件体验! 当我们想要预览自己老去的模样,或者给照片增添一丝岁月的韵味时,变老特效成为了一个热门选择。那么,这种神奇的效果是如何实现的呢?又有哪些软件可以让我们轻松体验呢&am…