第二十八期:Java线程池的四种用法与使用场景

线程池的作用主要是为了提升系统的性能以及使用率。文章刚开始就提到,如果我们使用最简单的方式创建线程,如果用户量比较大,那么就会产生很多创建和销毁线程的动作,这会导致服务器在创建和销毁线程上消耗的性能可能要比处理实际业务花费的时间和性能更多。

作者:小涛

 一、如下方式存在的问题

new Thread() { @Override public void run() { // 业务逻辑 } 
}.start(); 

1、首先频繁的创建、销毁对象是一个很消耗性能的事情;2、如果用户量比较大,导致占用过多的资源,可能会导致我们的服务由于资源不足而宕机;3、综上所述,在实际的开发中,这种操作其实是不可取的一种方式。

二、使用线程池有什么优点

1、线程池中线程的使用率提升,减少对象的创建、销毁;2、线程池可以控制线程数,有效的提升服务器的使用资源,避免由于资源不足而发生宕机等问题;

三、线程池的四种使用方式

1、newCachedThreadPool

创建一个线程池,如果线程池中的线程数量过大,它可以有效的回收多余的线程,如果线程数不足,那么它可以创建新的线程。

public static void method() throws Exception { ExecutorService executor = Executors.newCachedThreadPool(); for (int i = 0; i < 5; i++) { final int index = i; Thread.sleep(1000); executor.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "  " + index); } }); } 
} 

执行结果

可以明显的看出,现在就需要几条线程来交替执行。

不足:这种方式虽然可以根据业务场景自动的扩展线程数来处理我们的业务,但是最多需要多少个线程同时处理缺是我们无法控制的;

优点:如果当第二个任务开始,第一个任务已经执行结束,那么第二个任务会复用第一个任务创建的线程,并不会重新创建新的线程,提高了线程的复用率;

2、newFixedThreadPool

这种方式可以指定线程池中的线程数。举个栗子,如果一间澡堂子最大只能容纳20个人同时洗澡,那么后面来的人只能在外面排队等待。如果硬往里冲,那么只会出现一种情景,摩擦摩擦...

首先测试一下最大容量为一个线程,那么会不会是我们预测的结果。

public static void method_01() throws InterruptedException { ExecutorService executor = Executors.newFixedThreadPool(1); for (int i = 0; i < 10; i++) { Thread.sleep(1000); final int index = i; executor.execute(() -> { try { Thread.sleep(2 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "  " + index); }); } executor.shutdown(); 
} 

 

优点:两个结果综合说明,newFixedThreadPool的线程数是可以进行控制的,因此我们可以通过控制最大线程来使我们的服务器打到最大的使用率,同事又可以保证及时流量突然增大也不会占用服务器过多的资源。

3、newScheduledThreadPool

该线程池支持定时,以及周期性的任务执行,我们可以延迟任务的执行时间,也可以设置一个周期性的时间让任务重复执行。 该线程池中有以下两种延迟的方法。

  • scheduleAtFixedRate

测试一

public static void method_02() { ScheduledExecutorService executor = Executors.newScheduledThreadPool(5); executor.scheduleAtFixedRate(new Runnable() { @Override public void run() { long start = new Date().getTime(); System.out.println("scheduleAtFixedRate 开始执行时间:" + DateFormat.getTimeInstance().format(new Date())); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } long end = new Date().getTime(); System.out.println("scheduleAtFixedRate 执行花费时间=" + (end - start) / 1000 + "m"); System.out.println("scheduleAtFixedRate 执行完成时间:" + DateFormat.getTimeInstance().format(new Date())); System.out.println("======================================"); } }, 1, 5, TimeUnit.SECONDS); 
} 

 

总结:以上两种方式不同的地方是任务的执行时间,如果间隔时间大于任务的执行时间,任务不受执行时间的影响。如果间隔时间小于任务的执行时间,那么任务执行结束之后,会立马执行,至此间隔时间就会被打乱。

  • scheduleWithFixedDelay

测试一

public static void method_03() { ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); executor.scheduleWithFixedDelay(new Runnable() { @Override public void run() { long start = new Date().getTime(); System.out.println("scheduleWithFixedDelay 开始执行时间:" + DateFormat.getTimeInstance().format(new Date())); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } long end = new Date().getTime(); System.out.println("scheduleWithFixedDelay执行花费时间=" + (end - start) / 1000 + "m"); System.out.println("scheduleWithFixedDelay执行完成时间:" + DateFormat.getTimeInstance().format(new Date())); System.out.println("======================================"); } }, 1, 2, TimeUnit.SECONDS); 
} 

测试二

public static void method_03() { ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); executor.scheduleWithFixedDelay(new Runnable() { @Override public void run() { long start = new Date().getTime(); System.out.println("scheduleWithFixedDelay 开始执行时间:" + DateFormat.getTimeInstance().format(new Date())); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } long end = new Date().getTime(); System.out.println("scheduleWithFixedDelay执行花费时间=" + (end - start) / 1000 + "m"); System.out.println("scheduleWithFixedDelay执行完成时间:" + DateFormat.getTimeInstance().format(new Date())); System.out.println("======================================"); } }, 1, 2, TimeUnit.SECONDS); 
} 

 

总结:同样的,跟scheduleWithFixedDelay测试方法一样,可以测出scheduleWithFixedDelay的间隔时间不会受任务执行时间长短的影响。

4、newSingleThreadExecutor

这是一个单线程池,至始至终都由一个线程来执行。

public static void method_04() { ExecutorService executor = Executors.newSingleThreadExecutor(); for (int i = 0; i < 5; i++) { final int index = i; executor.execute(() -> { try { Thread.sleep(2 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "   " + index); }); } executor.shutdown(); 
} 

 

四、线程池的作用

线程池的作用主要是为了提升系统的性能以及使用率。文章刚开始就提到,如果我们使用最简单的方式创建线程,如果用户量比较大,那么就会产生很多创建和销毁线程的动作,这会导致服务器在创建和销毁线程上消耗的性能可能要比处理实际业务花费的时间和性能更多。线程池就是为了解决这种这种问题而出现的。

同样思想的设计还有很多,比如数据库连接池,由于频繁的连接数据库,然而创建连接是一个很消耗性能的事情,所有数据库连接池就出现了。

阅读目录(置顶)(长期更新计算机领域知识)

阅读目录(置顶)(长期更新计算机领域知识)

阅读目录(置顶)(长期科技领域知识)

歌谣带你看java面试题

 

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

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

相关文章

php连接mysql遇到的问题: (HY000/1130) 和 [caching_sha2_password]

说明一下我的mysql是安装在虚拟机上的 所以遇到的第一个问题就是访问问题 解决&#xff1a; update user set host % where user root; 重启mysql服务 试了很多方法&#xff0c;也找了很多方法只有这个可行。 问题2&#xff0c; 解决&#xff1a; https://www.cnblogs.com/un…

847. Shortest Path Visiting All Nodes(一)

输入&#xff1a;一个无向图&#xff0c;各个节点的标签是0、1、2…N-1。graph[i][j]表示从节点i到节点j有一条边。 输出&#xff1a;返回每个节点都访问一遍需要的最少步骤。 规则&#xff1a;各个节点可以重复访问。 分析&#xff1a;  如果可以知道从每个节点开始&#xf…

第二十九期:程序员们该如何破局!

我是实打实的程序员一枚&#xff0c;身为一个过来人&#xff0c;我觉得有必要说几点针对程序员们的破局思维&#xff0c;希望能解决不少人的迷茫与困惑。 作者&#xff1a;stormzhang 新读者可能不知道&#xff0c;老读者都晓得&#xff0c;虽说现在转身做了自媒体&#xff0c…

[Leetcode][第75题][JAVA][颜色分类][双(三)指针][计数排序]

【问题描述】[中等] 【解答思路】 1. 三指针 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(1) class Solution {public void sortColors(int[] nums) {int n nums.length;int p0 0, p2 n - 1;for (int i 0; i < p2; i) {while (i < p2 && nums[i] …

第三十期:程序员报告:男性占比超87% 北京月薪12184元最高

1024“程序员节”&#xff0c;58同城招聘研究院发布程序员行业大数据报告显示&#xff0c;程序员男性占比高达87.29%。 作者&#xff1a;朝晖 1024“程序员节”&#xff0c;58同城招聘研究院发布程序员行业大数据报告显示&#xff0c;程序员男性占比高达87.29%&#xff0c;北…

[Leetcode][LCP 19][JAVA][秋叶收藏集][动态规划]

【问题描述】[中等] 【解答思路】 1. 动态规划 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(N) class Solution {public int minimumOperations(String leaves) {if (leaves null || leaves "") { // 排除 不合法参数情况return 0;}int length leave…

第三十一期:QQ for Linux 复活,微信 for Linux 还远吗?

网友通过分析龙芯处理器的生态支持计划与近期 QQ for Linux 支持 MIPS 架构的事实&#xff0c;结合当前国产自主研发的大背景&#xff0c;认为距离微信 for Linux 的发布也不远了。 10 月 24 日晚间&#xff0c;腾讯突然发布了沉寂多年的 QQ for Linux 新版本&#xff0c;引起了…

[Leetcode][第141、142题][JAVA][环形链表][哈希表][快慢指针][数学推理]

【问题描述】[中等] 【解答思路】 141 每次遍历到一个节点时&#xff0c;判断该节点此前是否被访问过。 具体地&#xff0c;我们可以使用哈希表来存储所有已经访问过的节点。每次我们到达一个节点&#xff0c;如果该节点已经存在于哈希表中&#xff0c;则说明该链表是环形链…

样式集合

box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.3);转载于:https://www.cnblogs.com/xmyd/p/10943567.html

[Leetcode][第1002题][JAVA][查找常用字符][计数][HashMap]

【问题描述】[简单] 【解答思路】 计数法 1. minfreq存放最终重复字母的个数 freq存放每次遍历字符串的字母个数 2. minfreq初始化最大值&#xff0c;每遍历一个字符串后&#xff0c;比较minfreq[i]、freq[i]的大小&#xff0c;minfreq[i]更新为两者的最小值。 3. 根据minf…

第三十三期:连接池中非常关键的两个参数,到底是干啥用的?

说来惭愧&#xff0c;从事互联网开发好些年了&#xff0c;有些概念一直没有彻底搞清楚。其中之一就是,ttp client配置连接池的时候,maxConnectionsPerHost,和maxTotalConnections,在网上搜了一圈&#xff0c;发现很多都讲的含含糊糊的。 作者&#xff1a;资深开发讲技术 背景 …

一个密码经过多次MD5加密能否提高安全性?Java MD5盐值加解密

什么是MD5? MD5&#xff08;Message Digest Algorithm 5&#xff0c;信息摘要算法5&#xff09;&#xff0c;是计算机广泛使用的摘要算法&#xff08;又称哈希算法&#xff09;之一。MD5是将一段信息&#xff0c;通过其不可逆的字符串变换算法&#xff0c;产生了唯一的MD5信息…

[Leetcode][第24题][JAVA][两两交还的链表中的节点][递归][三指针]

【问题描述】[中等] 【解答思路】 1. 递归 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(N) class Solution {public ListNode swapPairs(ListNode head) {if(head null || head.next null){return head;}ListNode next head.next;head.next swapPairs(next.next…

第三十四期:花了一个星期,我终于把RPC框架整明白了!

RPC(Remote Procedure Call)&#xff1a;远程过程调用&#xff0c;它是一种通过网络从远程计算机程序上请求服务&#xff0c;而不需要了解底层网络技术的思想。 作者&#xff1a;李金葵 RPC(Remote Procedure Call)&#xff1a;远程过程调用&#xff0c;它是一种通过网络从远…

[Leetcode][第116 117题][JAVA][填充每个节点的下一个右侧节点指针][BFS][链表前驱节点]

【问题描述】[中等] 【解答思路】 1. BFS层次遍历思想 &#xff08;通用&#xff09; 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(N) public Node connect(Node root) {if (root null)return root;Queue<Node> queue new LinkedList<>();queue.add(r…

Windows Server2012 R2 无法安装.NET Framework 3.5的解决方法

Windows server 2012R2&#xff0c;自带的是.NET Framework 4.5,如果想装SQL server2008或者SQL server2012就需要安装 .ENT Framework 3.5或者2.0的版本&#xff0c;建议安装 .NET3.5 版本&#xff0c;我本人亲测过&#xff0c;成功了&#xff01; 安装不成功错误分析&#x…

第三十五期:网络爬虫是啥玩意儿?有什么用呢?

在这个用数据说话的时代&#xff0c;数据是一件极其重要的事情&#xff0c;怎样才能抓取到完整以及全面的数据呢&#xff1f;这并不是一件容易的事情。 作者&#xff1a;呦呦科学馆 如果想要做好大数据的分析&#xff0c;单单依靠一己之力或者是周边的数据是远远不够的&#x…

第三十六期:学 Java 网络爬虫,需要哪些基础知识?

说起网络爬虫&#xff0c;大家想起的估计都是 Python &#xff0c;诚然爬虫已经是 Python 的代名词之一&#xff0c;相比 Java 来说就要逊色不少。有不少人都不知道 Java 可以做网络爬虫&#xff0c;其实 Java 也能做网络爬虫而且还能做的非常好&#xff0c;在开源社区中有不少…

前端之盒子模型

CSS之盒子模型 margin: 用于控制元素与元素之间的距离&#xff1b;margin的最基本用途就是控制元素周围空间的间隔&#xff0c;从视觉角度上达到相互隔开的目的。padding: 用于控制内容与边框之间的距离&#xff1b;Border(边框): 围绕在内边距和内容外的边框。Content(内容): …

[Leetcode][第977题][JAVA][有序数组的平方][排序][双指针]

【问题描述】[简单] 【解答思路】 1. 排序 平方后排序 没有使用排序的特性 时间复杂度&#xff1a;O(NlogN) 空间复杂度&#xff1a;O(1) class Solution {public int[] sortedSquares(int[] A) {int[] ans new int[A.length];for (int i 0; i < A.length; i) {ans[i] …