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

java八股文面试[多线程]——newWorkStealingPool

newWorkStealingPool是什么?
newWorkStealingPool简单翻译是任务窃取线程池。

newWorkStealingPool 是Java8添加的线程池。和别的4种不同,它用的是ForkJoinPool

使用ForkJoinPool的好处是,把1个任务拆分成多个“小任务”,把这些“小任务”分发到多个线程上执行。这些“小任务”都执行完成后,再将结果合并

之前的线程池中,多个线程共有一个阻塞队列,而newWorkStealingPool 中每一个线程都有一个自己的队列。

当线程发现自己的队列没有任务了,就会到别的线程的队列里获取任务执行。可以简单理解为”窃取“。

一般是自己的本地队列采取LIFO(后进先出)窃取时采用FIFO(先进先出),一个从头开始执行,一个从尾部开始执行,由于偷取的动作十分快速,会大量降低这种冲突,也是一种优化方式。

它有2种实现,如下:
无参
public static ExecutorService newWorkStealingPool() {return new ForkJoinPool(Runtime.getRuntime().availableProcessors(),ForkJoinPool.defaultForkJoinWorkerThreadFactory,null, true);
}

Runtime.getRuntime().availableProcessors()是获取当前系统可以的CPU核心数。

有参

就一个参数parallelism,可以自定义并行度。

public static ExecutorService newWorkStealingPool(int parallelism) {return new ForkJoinPool(parallelism,ForkJoinPool.defaultForkJoinWorkerThreadFactory,null, true);
}
newWorkStealingPool测试案例
public class Thread08_WorkStealing {public static void main(String[] args) {ExecutorService executorService = Executors.newWorkStealingPool(3);for (int i=1; i<= 100; i++){executorService.submit(new MyWorker(i));}while (true){}}
}

运行结果:

ForkJoinPool-1-worker-2正在执行,数值:2
ForkJoinPool-1-worker-1正在执行,数值:1
ForkJoinPool-1-worker-3正在执行,数值:3
ForkJoinPool-1-worker-2正在执行,数值:5
ForkJoinPool-1-worker-1正在执行,数值:4
ForkJoinPool-1-worker-3正在执行,数值:6
ForkJoinPool-1-worker-2正在执行,数值:8
ForkJoinPool-1-worker-3正在执行,数值:9
ForkJoinPool-1-worker-1正在执行,数值:7
。。。。。。

发现确实创建了3个线程来执行任务。

把newWorkStealingPool(3)中参数去掉改成newWorkStealingPool(),结果如下:

ForkJoinPool-1-worker-1正在执行,数值:1
ForkJoinPool-1-worker-3正在执行,数值:3
ForkJoinPool-1-worker-2正在执行,数值:2
ForkJoinPool-1-worker-4正在执行,数值:4
ForkJoinPool-1-worker-5正在执行,数值:5
ForkJoinPool-1-worker-6正在执行,数值:6
ForkJoinPool-1-worker-7正在执行,数值:7
ForkJoinPool-1-worker-0正在执行,数值:8
ForkJoinPool-1-worker-6正在执行,数值:10
ForkJoinPool-1-worker-2正在执行,数值:13
ForkJoinPool-1-worker-0正在执行,数值:15
。。。。。。

发现确实创建了8个线程共同完成任务,因为我CPU有8个核。

ThreadPoolExecutor的核心点

在ThreadPoolExecutor中只有一个阻塞队列存放当前任务

image.png

ForkJoinPool从名字上就能看出一些东西。当有一个特别大的任务时,如果采用上述方式,这个大任务只能会某一个线程去执行。ForkJoin第一个特点是可以将一个大任务拆分成多个小任务,放到当前线程的阻塞队列中。其他的空闲线程就可以去处理有任务的线程的阻塞队列中的任务

image.png

来一个比较大的数组,里面存满值,计算总和

单线程处理一个任务:

/** 非常大的数组 */
static int[] nums = new int[1_000_000_000];
// 填充值
static{for (int i = 0; i < nums.length; i++) {nums[i] = (int) ((Math.random()) * 1000);}
}
public static void main(String[] args) {// ===================单线程累加10亿数据================================System.out.println("单线程计算数组总和!");long start = System.nanoTime();int sum = 0;for (int num : nums) {sum += num;}long end = System.nanoTime();System.out.println("单线程运算结果为:" + sum + ",计算时间为:" + (end  - start));
}

多线程分而治之的方式处理:

/** 非常大的数组 */
static int[] nums = new int[1_000_000_000];
// 填充值
static{for (int i = 0; i < nums.length; i++) {nums[i] = (int) ((Math.random()) * 1000);}
}
public static void main(String[] args) {// ===================单线程累加10亿数据================================System.out.println("单线程计算数组总和!");long start = System.nanoTime();int sum = 0;for (int num : nums) {sum += num;}long end = System.nanoTime();System.out.println("单线程运算结果为:" + sum + ",计算时间为:" + (end  - start));// ===================多线程分而治之累加10亿数据================================// 在使用forkJoinPool时,不推荐使用Runnable和Callable// 可以使用提供的另外两种任务的描述方式// Runnable(没有返回结果) ->   RecursiveAction// Callable(有返回结果)   ->   RecursiveTaskForkJoinPool forkJoinPool = (ForkJoinPool) Executors.newWorkStealingPool();System.out.println("分而治之计算数组总和!");long forkJoinStart = System.nanoTime();ForkJoinTask<Integer> task = forkJoinPool.submit(new SumRecursiveTask(0, nums.length - 1));Integer result = task.join();long forkJoinEnd = System.nanoTime();System.out.println("分而治之运算结果为:" + result + ",计算时间为:" + (forkJoinEnd  - forkJoinStart));
}private static class SumRecursiveTask extends RecursiveTask<Integer>{/** 指定一个线程处理哪个位置的数据 */private int start,end;private final int MAX_STRIDE = 100_000_000;//  200_000_000: 147964900//  100_000_000: 145942100public SumRecursiveTask(int start, int end) {this.start = start;this.end = end;}@Overrideprotected Integer compute() {// 在这个方法中,需要设置好任务拆分的逻辑以及聚合的逻辑int sum = 0;int stride = end - start;if(stride <= MAX_STRIDE){// 可以处理任务for (int i = start; i <= end; i++) {sum += nums[i];}}else{// 将任务拆分,分而治之。int middle = (start + end) / 2;// 声明为2个任务SumRecursiveTask left = new SumRecursiveTask(start, middle);SumRecursiveTask right = new SumRecursiveTask(middle + 1, end);// 分别执行两个任务left.fork();right.fork();// 等待结果,并且获取sumsum = left.join() + right.join();}return sum;}
}

最终可以发现,这种累加的操作中,采用分而治之的方式效率提升了2倍多。

但是也不是所有任务都能拆分提升效率,首先任务得大,耗时要长

知识来源:

Java多线程(十四) Java8 newWorkStealingPool 线程池_瑟王的博客-CSDN博客

相关文章:

java八股文面试[多线程]——newWorkStealingPool

newWorkStealingPool是什么&#xff1f; newWorkStealingPool简单翻译是任务窃取线程池。 newWorkStealingPool 是Java8添加的线程池。和别的4种不同&#xff0c;它用的是ForkJoinPool。 使用ForkJoinPool的好处是&#xff0c;把1个任务拆分成多个“小任务”&#xff0c;把这…...

STM32--RTC实时时钟

文章目录 Unix时间戳时间戳转换BKPRTC简介RTC框图硬件电路RTC的注意事项RTC时钟实验工程 Unix时间戳 Unix 时间戳是从1970年1月1日&#xff08;UTC/GMT的午夜&#xff09;开始所经过的秒数&#xff0c;不考虑闰秒。 时间戳存储在一个秒计数器中&#xff0c;秒计数器为32位/64…...

【N2】例题学习笔记

N2例题 《新"日本语能力测试"例题集》 听力原稿(PDF) 【10】 【問い】この筆者から見た「仕事ができる人」の特徴はどんなことか。 【提问】这位作者认为&#xff0c;仕事能力强的人具有什么特点呢&#xff1f; 【11】 文章 下の文章は、企業のあり方について…...

【数据分享】2006-2021年我国城市级别的道路、桥梁、管线建设相关指标(10多项指标)

《中国城市建设统计年鉴》中细致地统计了我国城市市政公用设施建设与发展情况&#xff0c;在之前的文章中&#xff0c;我们分享过基于2006-2021年《中国城市建设统计年鉴》整理的2006—2021年我国城市级别的市政设施水平相关指标、2006-2021年我国城市级别的各类建设用地面积数…...

视觉SLAM14讲笔记-第7讲-视觉里程计2

直接法的引出 直接法是视觉里程计另一个主要分支&#xff0c;它与特征点法有很大的不同。 使用特征点法估计相机运动时&#xff0c;我们把特征点看作固定在三维空间的不动点。根据它们在相机中的投影位置&#xff0c;通过最小化重投影误差来优化相机运动。 相对地&#xff0c…...

MySQL——单行函数和分组函数

2023.9.3 单行函数的SQL语句学习笔记如下&#xff1a; #常见单行函数介绍&#xff08;部分省略&#xff09; #字符函数 #将姓变大写&#xff0c;名变小写&#xff0c;然后拼接。 SELECT CONCAT(UPPER(last_name), ,LOWER(first_name)) AS 姓名 FROM employees; # 姓名中首字符…...

百度百科词条怎么更新?怎么能顺利更新百科词条?

企业和个人百度百科词条的更新对于他们来说都具有重要的意义&#xff0c;具体如下&#xff1a; 对企业来说&#xff1a; 塑造品牌形象&#xff1a;百度百科是一个常被用户信任并参考的知识平台&#xff0c;通过更新企业词条可以提供准确、全面的企业信息&#xff0c;帮助企业塑…...

PPT怎么转换为PDF格式,收藏这两个在线工具。

PPT是一种常用的演示文稿格式&#xff0c;它可以包含丰富的动画效果和超链接&#xff0c;让你的内容更加生动和有趣。但是&#xff0c;如果你想将PPT分享给别人&#xff0c;或者在不同的设备上查看&#xff0c;你可能会遇到一些问题&#xff0c;比如&#xff1a; PPT文件太大&a…...

八大排序算法----堆排序

堆排序的基本步骤&#xff1a;&#xff08;以从大到小的顺序排序为例&#xff09; 1.构建大顶堆&#xff08;每个结点的值都大于或等于其左右孩子结点的值&#xff09; 2.排序&#xff1a;每次堆顶的元素取出来&#xff08;整个堆中值最大&#xff09;&#xff0c;与最后一个…...

Docker Desktop 设置镜像环境变量

点击run 展开Optional settings container name &#xff1a;容器名称 Ports&#xff1a;根据你需要的端口进行输入&#xff0c;不输入则默认 后面这个 比如我这个 5432 Volumes&#xff1a;卷&#xff0c;也就是做持久化 需要docker 数据保存的地方 Environment variables…...

springboot之一:配置文件(内外部配置优先顺序+properties、xml、yaml基础语法+profile动态切换配置、激活方式)

配置的概念&#xff1a; Spring Boot是基于约定的&#xff0c;所以很多配置都有默认值&#xff0c;但如果想使用自己的配置替换默认配置的话&#xff0c;就可以使用application.properties或者application.yml(application.yaml)进行配置。 注意配置文件的命名必须是applicat…...

涛然自得周刊(第 5 期):蝲蛄吟唱的地方

作者&#xff1a;何一涛 日期&#xff1a;2023 年 8 月 20 日 涛然自得周刊主要精选作者阅读过的书影音内容&#xff0c;不定期发。历史周刊内容可以看这里。 电影 《沼泽深处的女孩》 改编自小说《蝲蛄吟唱的地方》&#xff0c;主角是一位在沼泽地独自生活并长大的女孩&…...

Android Ble蓝牙App(七)扫描过滤

Ble蓝牙App&#xff08;七&#xff09;扫描过滤 前言目录正文一、增加菜单二、使用MMKV① 添加依赖② 封装MMKV③ 使用MMKV 三、过滤空设备名四、过滤Mac地址五、过滤RSSI六、源码 前言 在上一篇文章中了解了MTU的相关知识以及对于设备操作信息的展示&#xff0c;本篇文章中将增…...

小程序当前页面栈以及跳转

1.调用页面栈刷新接口 let pages getCurrentPages(); //当前页面栈 if (pages.length > 1) { let beforePage pages[pages.length - 2]; //获取上一个页面实例对象 beforePage.$vm.getActivityLi…...

jQuery获取表单的值val()

&#xff08;1&#xff09;页面中有很多元素&#xff0c;包括表单中的输入项&#xff0c;如输入文本框等&#xff1b;获取、设置、输入文本框的值&#xff1b;val()方法。 &#xff08;2&#xff09;也包括<p>、<span>等元素&#xff1b;获取、设置这些元素的文本…...

【专栏必读】数字图像处理(MATLAB+Python)专栏目录导航及学习说明

文章目录 第一章&#xff1a;绪论第二章&#xff1a;数字图像处理基础第三章&#xff1a;图像基本运算第四章&#xff1a;图像的正交变换第五章&#xff1a;图像增强第六章&#xff1a;图像平滑第七章&#xff1a;图像锐化第八章&#xff1a;图像复原第九章&#xff1a;图像形态…...

2023年非证券类投资银行业发展报告

第一章 行业概况 非证券投资银行业是一个专门为公司、政府和高净值个人提供金融服务的行业&#xff0c;与传统的证券投资银行不同&#xff0c;其主要业务不涉及证券交易&#xff0c;而是注重为客户提供咨询服务、融资和投资管理等服务。 非证券投资银行通常涉及的业务领域包括…...

Matlab 如何把频谱图的纵坐标设置为分贝刻度

Matlab 如何把频谱图的纵坐标设置为分贝刻度 Matlab代码如下&#xff1a; % 如何把频谱图的纵坐标设置为分贝刻度 % % pr2_2_6 clc; clear; close all;load pr2_2_6_sndata1.mat % 读入数据 X fft(y); % FFT n2 1:L/21; % 计算正频率…...

VUE写后台管理(2)

VUE写后台管理&#xff08;2&#xff09; 1.环境2.Element界面3.Vue-Router路由后台1.左导航栏2.上面导航条 1.环境 1.下载管理node版本的工具nvm&#xff08;Node Version Manager&#xff09; 2.安装node(vue工程的环境管理工具)&#xff1a;nvm install 16.13.0 3.安装vue工…...

RHCSA8.2

Node1 配置您的系统以使用默认存储库 配置您 的系统以使用默认存储库YUM 存储库已可以从 http://foundation0.ilt.example.com/dvd/BaseOS 和 http://foundation0.ilt.example.com/dvd/AppStream 使用配置您的系统&#xff0c;以将这些位置用作默认存储库[rootclear ~]# cat …...

修改linux中tomcat的端口

随便修改一个 以8055为例子 开放8081端口 firewall-cmd --permanent --add-port8081/tcp firewall-cmd --reload firewall-cmd --list-all...

学妹学Java(一)

⭐简单说两句⭐ 作者&#xff1a;后端小知识 CSDN个人主页&#xff1a;后端小知识 &#x1f50e;GZH&#xff1a;后端小知识 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; Hello&#xff0c;亲爱的各位友友们&#xff0c;好久不见&#xff0…...

湖南省副省长秦国文一行调研考察亚信科技

9月5日&#xff0c;湖南省人民政府党组成员、副省长秦国文一行到亚信科技调研考察&#xff0c;亚信科技高级副总裁陈武主持接待。 图&#xff1a;双方合影 在亚信科技创新展示中心&#xff0c;秦国文了解了亚信科技在5G、算力网络、人工智能、大数据等前沿领域的创新探索&…...

k8s部署redis 3主3从

k8s部署redis6节点&#xff0c;组成3主3从集群模式 一般来说&#xff0c;redis部署有三种模式。 单实例模式&#xff0c;一般用于测试环境。 哨兵模式 集群模式后两者用于生产部署 哨兵模式 在redis3.0以前&#xff0c;要实现集群一般是借助哨兵sentinel工具来监控master节点…...

Vue2安装vuex和vue-router报错处理

Vue2安装vuex和vue-router报错处理 Vue2.6安装VuexVue2.6安装vue-router Vue2.6安装Vuex 报错信息 处理方法 #查看vuex版本 npm view vuex versions --json #安装合适版本 npm install vuex3.6.2 --saveVue2.6安装vue-router 报错信息 处理方法 #查看vue-router版本 npm…...

算法leetcode|79. 单词搜索(rust重拳出击)

文章目录 79. 单词搜索&#xff1a;样例 1&#xff1a;样例 2&#xff1a;样例 3&#xff1a;提示&#xff1a;进阶&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 79. 单词搜索&#xff1a; …...

2023年高教社杯全国大学生数学建模竞赛参赛事项注意

MathClub数模资源&#xff0c;含专属思路 资源链接&#xff1a;点击这里获取众多数模资料、思路精讲、论文模板latex和word、学习书籍等 2023高教社杯数学建模国赛–赛前准备 一年一度的数学建模国赛要来啦&#xff01;&#xff01;&#xff01;小编仔细阅读了比赛官方网站上…...

数学建模--逻辑回归算法的Python实现

首先感谢CSDN上发布吴恩达的机器学习逻辑回归算法任务的各位大佬. 通过大佬的讲解和代码才勉强学会. 这篇文章也就是简单记录一下过程和代码. CSDN上写有关这类文章的大佬有很多,大家都可以多看一看学习学习. 机器学习方面主要还是过程和方法. 这篇文章只完成了线性可分方面的任…...

Qt6_贪吃蛇Greedy Snake

贪吃蛇Greedy Snake 1分析 首先这是一个贪吃蛇界面&#xff0c;由一个长方形边框和一只贪吃蛇组成 默认开局时&#xff0c;贪吃蛇身体只有3个小方块&#xff0c;使用画笔画出 1.1如何移动 对于蛇的移动&#xff0c;有2种方法 在一定时间范围内(定时器)&#xff0c;未对游戏…...

Credo推出业界首款单片集成CMOS VCSEL驱动器的800G光DSP芯片

针对AOC及短距&#xff08;SR&#xff09;光模块优化的新型Credo DSP&#xff0c;适用于下一代超大规模数据中心/AI应用 加州圣何塞和中国深圳&#xff0c;2023年9月6日——Credo Technology&#xff08;纳斯达克股票代码&#xff1a;CRDO&#xff09;今日发布两款新品&#x…...

刚做的网站适合做外链吗/苏州seo

是40&#xff0c; 在建立数据表的时候要注意一下&#xff0c; 用char类型就可以了转载于:https://www.cnblogs.com/souroot/archive/2012/10/20/2732456.html...

小企业网站建设系统哪个好/徐汇网站建设

题目 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode-cn.com/problems/reverse-nodes-in-k-group 著作权归领扣网络所有。商业转载请联系官方授权&#xff0c;非商业转载请注明出处。 给你一个链表&#xff0c;每 k 个节点一组进行翻…...

做盗链电影网站怎么样/个人免费开发app

类型&#xff1a;便捷生活大小&#xff1a;101.2MB评分&#xff1a;10平台&#xff1a;ofo共享单车貌似出了点问题&#xff01;今天很多朋友都无法登录、显示网络错误&#xff0c;还无法结算&#xff0c;这是怎么回事&#xff0c;又该怎么办呢&#xff1f;来看看吧&#xff01;…...

云南做网站多少钱/seo搜索工具栏

举例来说&#xff0c;连续相同的3位数字的正则表达式的标准语法是&#xff1a; ([\d])\1{2}但是如果在java代码中这么写&#xff0c;就会出现语法错误&#xff0c;如下&#xff1a; String regEx "([\d])\1{2}";考虑到\符号在java字符串的语法中属于转义符&#xff…...

手机怎么做网站服务器/哪个网站学seo是免费的

说的更通俗一点&#xff0c;域名迁移就是修改域名的权威DNS&#xff0c;即将域名ABC.COM的原权威DNS由A迁移到B。实际工作中最常见的形式是将域名转到另一家DNS服务商来解析。本文就域名迁移过程中几个值得关注的问题讨论一下。 一、为什么要域名迁移?通常情况下&#xff0c;…...

备案后修改网站名称/一点优化

堆和栈是两种内存分配的统称。 一.栈 栈会存放函数的局部变量&#xff0c;函数的返回地址等。栈有"LIFO"(后进先出)的特点。栈由操作系统分配&#xff0c;自动回收.栈的大小受到限制。在x86体系下&#xff0c;栈一般通过esp 指向栈帧顶部&#xff0c;ebp指向底部不…...