线程池怎么用?---实例讲解

线程池使用实例

先写一个配置类

/*** 线程池配置*/
@Configuration
public class ThreadPoolConfig {//定义线程前缀public static final String NAME_PRE="test";/*** ExecutorService 这个对象就是线程池,可以点进去他的源码看看* @Bean,将getExecutor()方法返回的对象交给Spring管理*/@Beanpublic static ExecutorService getExecutor(){/***方法一*ExecutorBuilder e=new ExecutorBuilder();*e.setAllowCoreThreadTimeOut(false);**//**方法二直接Builder赋值**/return ExecutorBuilder.create().setCorePoolSize(8).setMaxPoolSize(16).setKeepAliveTime(60, TimeUnit.SECONDS).setHandler(new ThreadPoolExecutor.CallerRunsPolicy()).setWorkQueue(new LinkedBlockingDeque<>(2000)).setThreadFactory(ThreadFactoryBuilder.create().setNamePrefix(NAME_PRE).build()).setAllowCoreThreadTimeOut(false).build();}
}
  • ExecutorService 这个对象是线程池
  • @Bean,在项目启动时执行ExecutorService类的方法,返回一个对象交给spring管理。
  • @Configuration,配置注解,在项目启动时,首先执行这个类的代码。
  • 返回的对象第一种方法用set方法去赋值;第二种用Builder赋值。

参数内容为数字也通常为魔法值

方法1、可以放到配置文件中(yml配置)
threadpool:corepoolsize: 8maxPoolSize: 16# 队列大小dequesize: 2000# 线程前缀namepre: test-
方法2、设置静态常量
//定义线程前缀
public static final String NAME_PRE="test";.setThreadFactory(ThreadFactoryBuilder.create().setNamePrefix(NAME_PRE).build())

这样一个线程池就建好了

写好了怎么用呢?

由于ExecutorService是一个interface,且交给了spring管理,所以直接注入使用。 这里在Impl注入。

@Resource
private ExecutorService executorService;

写一个测试尝试一下:

Service中写接口
/**Service中写接口**/void test() throws InterruptedException;

Impl中重写方法(先模拟不用线程池)

使用@SentinelResource 注解 value指定资源的名称,blockHandler用于指定服务限流后的后续处理逻辑。

依赖:

<!--    如果要使用@SentinelResource必须添加此依赖    -->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-annotation-aspectj</artifactId><version>1.8.1</version>
</dependency>
/**Impl中重写方法**/@SentinelResource(value = "test",blockHandler="exceptionHandler")
@Override
public Boolean test() throws InterruptedException {/**模拟业务场景耗时**/Thread.sleep(100000);return true;
}
controller中调用接口
/**controller中调用接口**/@GetMapping("/open/test")
public Boolean test() throws InterruptedException {userService.test();return Boolean.TRUE;
}

我们可以看到,由于睡眠操作,访问接口一直显示加载状态

0

怎么用线程池?两个方法

方法一 注解方式(用的不多)

方法二 使用CompletableFuture

@Override
public void test() throws InterruptedException {log.info("进来了");CompletableFuture.runAsync(()->{try {log.info("进来了1111");/**模拟业务场景耗时**/Thread.sleep(100000);} catch (InterruptedException e) {e.printStackTrace();}},executorService);}

浏览器访问会立即打开

0

后台日志也表明已将任务交给线程池

0

多执行几次看看

0

我们发现,线程池到 test7 后就没有了,因为我们设置的核心线程数为8,这8个线程都在帮我们干活,再多的线程任务将放置到队列中。

等一小会....

发现刚刚被放入队列未执行的任务又被执行了,因为有线程执行完任务,就去队列中拿新任务去执行了。

0

使用多线程的三种形式

1、将任务交给线程池去做,至于成不成功、需不需要返回值,不关注。

例如新增用户的三个任务交给线程池,不关注有没有成功。当主线程将所有任务交给线程池后,主线程就认为新增用户这个任务完成了,去进行下一项任务。

===> 适用于更新操作,不关注返回值

2、将任务交给线程池去做,需要等待任务返回的结果。当主线程将任务交给线程池后,进入阻塞状态,直到获得所有的返回值。

例如将新增用户改为查询用户信息,我们知道查询一定是要返回结果的,所以主线程需要等待线程池内的任务执行完毕,他才能继续下一项任务,在这期间主线程一直处于阻塞状态。

===> 适用于多IO操作,如:for循环查数据库、循环调用http接口查询、多次查询数据库操作

模拟一下多线程查询

@Override
public void test() throws InterruptedException {log.info("进来了");//QueryBo为构建的返回值QueryBO queryBO=new QueryBO();//获取开始时间long start = System.currentTimeMillis();//创建线程,将任务放到线程池CompletableFuture<Void> query1 = CompletableFuture.runAsync(() -> {Boolean aBoolean = null;try {aBoolean = query1();} catch (InterruptedException e) {e.printStackTrace();}queryBO.setQuery1(aBoolean);}, executorService);//创建线程,将任务放到线程池CompletableFuture<Void> query2 =CompletableFuture.runAsync(()-> {Boolean aBoolean = null;try {aBoolean = query2();} catch (InterruptedException e) {e.printStackTrace();}queryBO.setQuery2(aBoolean);},executorService);//创建线程,将任务放到线程池CompletableFuture<Void> query3=CompletableFuture.runAsync(()-> {Boolean aBoolean = null;try {aBoolean = query3();} catch (InterruptedException e) {e.printStackTrace();}queryBO.setQuery3(aBoolean);},executorService);//将这3个任务放到数组中CompletableFuture[] completableFutures=Stream.of(query1,query2,query3).collect(Collectors.toList()).toArray(new CompletableFuture[3]);//当数组里的任务都执行完,聚合一下,这行代码相当于将主线程阻塞住CompletableFuture.allOf(completableFutures).join();//打印时间戳long time = System.currentTimeMillis()-start;//allOf之后才会执行这句log,验证一下queryBOlog.info("查询结果{},时间差{}",queryBO,time);
}/*** 第一个查询,耗时3秒* @return* @throws InterruptedException*/
public Boolean query1()throws InterruptedException{log.info("进来了1");Thread.sleep(3000);return true;
}/*** 第二个查询,耗时1秒* @return* @throws InterruptedException*/
public Boolean query2()throws InterruptedException{log.info("进来了2");Thread.sleep(1000);return true;
}/*** 第三个查询,耗时5s* @return* @throws InterruptedException*/
public Boolean query3()throws InterruptedException{log.info("进来了3");Thread.sleep(5000);return false;
}

给一个QueryBO,Controller、Service代码都是不变的,上边有

@Data
public class QueryBO {private Boolean query1;private Boolean query2;private Boolean query3;
}

运行一下子,看看结果:

===> 不出意料的时间差是5秒左右,QueryBO中也有三个任务的返回值,说明三个查询是一起执行的。

===>重点代码是,以下两行,仔细研究

//将这3个任务放到数组中
CompletableFuture[] completableFutures=Stream.of(query1,query2,query3).collect(Collectors.toList()).toArray(new CompletableFuture[3]);//当数组里的任务都执行完,聚合一下,这行代码相当于将主线程阻塞住
CompletableFuture.allOf(completableFutures).join();

线程不安全问题

定义一个全局变量count=1;每个线程内都去操作这个count,让它+1操作,最后count的结果是什么?

多执行几次结果:

===>发现这个count并不是连续递增,说明多线程操作一个变量是不安全的,可能会被互相覆盖。

===>解决方法:加锁

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

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

相关文章

2024年甘肃省职业院校技能大赛(中职教师组)网络安全竞赛样题卷③

2024年甘肃省职业院校技能大赛&#xff08;中职教师组&#xff09;网络安全竞赛样题卷③ 2024年甘肃省职业院校技能大赛&#xff08;中职教师组&#xff09;网络安全竞赛样题卷③A模块基础设施设置/安全加固&#xff08;200分&#xff09;A-1任务一 登录安全加固&#xff08;Wi…

400页Python学习PDF笔记,全面总结零基础入门看这一篇足够了

我们都知道Python入门比较简单&#xff0c;但仍有很多想要学习的新手依然卡在基础的安装阶段&#xff0c;尽管如此&#xff0c;网络上的大部分的教程却对这些基础内容都是一带而过&#xff0c;导致许多新手朋友对这些基础知识一知半解&#xff0c;往往一个小问题都需要在网上查…

电脑回收站还原的文件在哪里找到?如何找回回收站还原的文件

电脑回收站是一种非常有用的功能&#xff0c;可以帮助我们恢复无意中删除的文件。然而&#xff0c;许多人可能不清楚还原的文件在哪里可以找到。本文将为您带来详细解答&#xff0c;并帮助您找回回收站还原的文件。 电脑回收站还原的文件在哪里找到 当我们使用电脑的回收站功…

element的el-date-picker时间控件,限制选择范围区间天数并且当前之后的日期不可选

element的el-date-picker时间控件&#xff0c;限制选择范围区间天数并且当前之后的日期不可选 HTML部分代码 <el-date-pickerv-model"dateRange"type"datetimerange"value-format"yyyy-MM-dd HH:mm:ss"range-separator"至"start-p…

element 弹窗在弹出后鼠标还可以点击页面其他元素

文章目录 需求分析需求 如下图所示,在点击弹出弹框后,支持 鼠标可点击弹框外的其他地方可拖拽弹框弹出弹出后不可有遮挡弹出样式可自定义 分析 官网:https://vxetable.cn/v4/#/table/start/install 安装 vxe-table 引入import {App, createApp }

速达软件全系产品任意文件上传漏洞复现 [附POC]

文章目录 速达软件全系产品任意文件上传漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 速达软件全系产品任意文件上传漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技…

centos安装Python3之后yum不能使用异常

场景&#xff1a; 需要在centos上安装Python3&#xff0c;但是安装Python3之后出现yum不能使用的问题。 问题描述 在centos上安装python3之后出现yum使用不了问题&#xff0c;使用yum会报如下信息&#xff1a; [roothadoop101~]# yum install wgetFile "/usr/bin/yum&q…

旋转框(obb)目标检测计算iou的方法

首先先定义一组多边形&#xff0c;这里的数据来自前后帧的检测结果 pre [[[860.0, 374.0], [823.38, 435.23], [716.38, 371.23], [753.0, 310.0]],[[829.0, 465.0], [826.22, 544.01], [684.0, 539.0], [686.78, 459.99]],[[885.72, 574.95], [891.0, 648.0], [725.0, 660.0]…

Matlab论文插图绘制模板第129期—函数网格曲面图

在之前的文章中&#xff0c;分享了Matlab函数折线图的绘制模板&#xff1a; 函数三维折线图&#xff1a; 进一步&#xff0c;再来分享一下函数网格曲面图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自…

activemq启动成功但web管理页面却无法访问

前提&#xff1a; 在linux启动activemq成功&#xff01;本地能ping通linux 处理方案&#xff1a; 确定防火墙是否关闭&#xff0c; 有两种处理方案&#xff1a;第一种-关闭防火墙&#xff1b;第二种-暴漏8161和61616两个端口 netstat -lnpt查看8161和61616端口 注意&#xf…

网络细节核心笔记

来源&#xff0c;做个笔记&#xff0c;讲的还蛮清楚通信原理-2.5 数据封装与传输05_哔哩哔哩_bilibili 交换机

慈善始于心,行善贵有恒 | 中创开展“寒冬送温暖”公益活动

岁暮隆冬&#xff0c;冷霜挂睫&#xff0c;前往尖山村的路上雾气弥漫&#xff0c;弯弯绕绕的山路需要开车一小时才能到达目的地。对许多人来说&#xff0c;这或许是一段漫长而艰辛的路程&#xff0c;但对于那些生活在山区的贫困儿童而言&#xff0c;这条山路却是通往外界的唯一…

IEEE 机器人最优控制开源库 Model-based Optimization for Robotics

系列文章目录 文章目录 系列文章目录前言一、开源的库和工具箱1.1 ACADO1.2 CasADi1.3 Control Toolbox1.4 Crocoddyl1.5 Ipopt1.6 Manopt1.7 LexLS1.8 NLOpt1.9 qpOASES1.10 qpSWIFT1.11 Roboptim 二、其他库和工具箱2.1 MUSCOD2.2 OCPID-DAE12.3 SNOPT 前言 机器人&#xff…

python爬虫基础html内容解析库BeautifulSoup

我们通过Requests请求url获取数据&#xff0c;请求把数据返回来之后就要提取目标数据&#xff0c;不同的网站返回的内容通常有多种不同的格式&#xff0c;一种是 json 格式&#xff0c;我们可以直接通过json.loads转换python的json对象处理。另一种 XML 格式的&#xff0c;还有…

【一个超简单的爬虫demo】探索新浪网:使用 Python 爬虫获取动态网页数据

探索新浪网&#xff1a;使用 Python 爬虫获取动态网页数据 引言准备工作选择目标新浪网的结构 编写爬虫代码爬取example.com爬取新浪首页部分内容解析代码注意&#xff1a; KeyError: href结果与展示 其他修改和适应注意事项 总结 引言 可以实战教爬虫吗&#xff0c;搭个环境尝…

快考个PMP,救救脆皮项目经理吧

最近&#xff0c;脆皮大学生在互联网上狠狠火了一把&#xff0c;各种稀奇古怪导致受伤的原因&#xff0c;各种意外骨折骨裂的方式&#xff0c;不断地刷新着网友的世界观。但喜番仔细思考&#xff0c;发现脆皮的不只是大学生&#xff0c;广大的打工人&#xff0c;特别是项目经理…

记录 | Mac微信双开

目的&#xff1a;在 mac 上微信双开 (1) 先打开并登录第一个微信&#xff1b; 2&#xff09;访达 -> 应用程序 -> 微信&#xff08;双指同时摁&#xff09;-> 显示包内容&#xff1b; 3&#xff09;依次打开以下⽂件夹 Contents -> MacOS -> 双击 WeChat 即可…

Ps:使用 Emoji 字符

Emoji 字符是一种在数字通讯中广泛使用的小图像或表情符号&#xff0c;用于表达情感、活动、物体、地点、天气情况等。 Emoji 源自日本&#xff0c;但现已成为全球数字沟通的一部分。这些字符通常是彩色的&#xff0c;并且能够在不同的设备和平台上保持一致性。 通常&#xff0…

EXPLAIN解析

针对以下sql进行解析 EXPLAIN SELECTdauk.id AS daukId,dasm.mailbox AS storeAccount,dau.id,dau.id AS userId,das.score AS score,das.sell_num AS sellNum,dapa.product_link AS productLink,dapa.able_category_ids AS ableCategoryIds,dac.parent_name AS parentName,da…

IPC/WHMA-A-620E- CN 中文版 2022 线缆及线束组件的要求与验收 ,已经发布

IPC/WHMA-A-620 - Revision E - : 线缆及线束组件的要求与验收Requirements and Acceptance for Cable and Wire Harness Assemblies 免费下载文件分享https://share.weiyun.com/h4MJ1oY8 IPC-WHMA-A-620E- CN 中文版 2022 线缆及线束组件的要求与验收.pdf_免费高速下载|百度网…