4种常用线程池

文章目录

          • 一.、线程池简介
            • 1. 线程池的概念:
            • 2. 线程池的工作机制
            • 3. 使用线程池的原因:
          • 二、四种常见的线程池详解
            • 1. 线程池的返回值ExecutorService简介
            • 2. 具体的4种常用的线程池案例
          • 三、 缓冲队列BlockingQueue和自定义线程池ThreadPoolExecutor

一.、线程池简介
1. 线程池的概念:

线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。

2. 线程池的工作机制

2.1 在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程,如果有,则将任务交给某个空闲的线程。
2.1 一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。

3. 使用线程池的原因:

多线程运行时间,系统不断的启动和关闭新线程,成本非常高,会过渡消耗系统资源,以及过渡切换线程的危险,从而可能导致系统资源的崩溃。这时,线程池就是最好的选择了。

二、四种常见的线程池详解
1. 线程池的返回值ExecutorService简介

ExecutorService是Java提供的用于管理线程池的接口。该接口的两个作用:控制线程数量和重用线程

2. 具体的4种常用的线程池案例

实现如下:(返回值都是ExecutorService)
2.1 Executors.newCacheThreadPool():可缓存线程池,先查看池中有没有以前建立的线程,如果有,就直接使用。如果没有,就建一个新的线程加入池中,缓存型池子通常用于执行一些生存期很短的异步型任务
示例代码:

package com.gblfy.xe;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class NewCachedThreadPoolTest {public static void main(String[] args) {// 创建一个可缓存线程池ExecutorService cachedThreadPool = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) {try {// sleep可明显看到使用的是线程池里面以前的线程,没有创建新的线程Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}cachedThreadPool.submit(new Runnable() {@Overridepublic void run() {// 打印正在执行的缓存线程信息System.out.println(Thread.currentThread().getName()+ "正在被执行");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});}}
}
输出结果:pool-1-thread-1正在被执行
pool-1-thread-1正在被执行
pool-1-thread-1正在被执行
pool-1-thread-1正在被执行
pool-1-thread-1正在被执行
pool-1-thread-1正在被执行
pool-1-thread-1正在被执行
pool-1-thread-1正在被执行
pool-1-thread-1正在被执行
pool-1-thread-1正在被执行

线程池为无限大,当执行当前任务时上一个任务已经完成,会复用执行上一个任务的线程,而不用每次新建线程

2.2 Executors.newFixedThreadPool(int n):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程。
示例代码:

package com.gblfy.xe;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class NewFixedThreadPoolTest {public static void main(String[] args) {// 创建一个可重用固定个数的线程池ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);for (int i = 0; i < 10; i++) {fixedThreadPool.execute(new Runnable() {@Overridepublic void run() {try {// 打印正在执行的缓存线程信息System.out.println(Thread.currentThread().getName()+ "正在被执行");Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}});}}
}
输出结果:pool-1-thread-1正在被执行
pool-1-thread-2正在被执行
pool-1-thread-3正在被执行
pool-1-thread-1正在被执行
pool-1-thread-2正在被执行
pool-1-thread-3正在被执行
pool-1-thread-1正在被执行
pool-1-thread-2正在被执行
pool-1-thread-3正在被执行
pool-1-thread-1正在被执行

因为线程池大小为3,每个任务输出打印结果后sleep 2秒,所以每两秒打印3个结果。
定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()

2.3 Executors.newScheduledThreadPool(int n):创建一个定长线程池,支持定时及周期性任务执行

延迟执行示例代码:

package com.gblfy.xe;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class NewScheduledThreadPoolTest {public static void main(String[] args) {//创建一个定长线程池,支持定时及周期性任务执行——延迟执行ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);//延迟1秒执行scheduledThreadPool.schedule(new Runnable() {@Overridepublic void run() {System.out.println("延迟1秒执行");}}, 1, TimeUnit.SECONDS);}
}

输出结果:延迟1秒执行

package com.gblfy.xe;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class NewScheduledThreadPoolTest {public static void main(String[] args) {//创建一个定长线程池,支持定时及周期性任务执行——延迟执行ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);//延迟1秒后每3秒执行一次scheduledThreadPool.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println("延迟1秒后每3秒执行一次");}}, 1, 3, TimeUnit.SECONDS);}
}

输出结果:

延迟1秒后每3秒执行一次
延迟1秒后每3秒执行一次
2.4 Executors.newSingleThreadExecutor():创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
示例代码:

package com.gblfy.xe;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class NewSingleThreadExecutorTest {public static void main(String[] args) {//创建一个单线程化的线程池ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();for (int i = 0; i < 10; i++) {final int index = i;singleThreadExecutor.execute(new Runnable() {@Overridepublic void run() {try {//结果依次输出,相当于顺序执行各个任务System.out.println(Thread.currentThread().getName() + "正在被执行,打印的值是:" + index);Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}});}}
}
输出结果:pool-1-thread-1正在被执行,打印的值是:0
pool-1-thread-1正在被执行,打印的值是:1
pool-1-thread-1正在被执行,打印的值是:2
pool-1-thread-1正在被执行,打印的值是:3
pool-1-thread-1正在被执行,打印的值是:4
pool-1-thread-1正在被执行,打印的值是:5
pool-1-thread-1正在被执行,打印的值是:6
pool-1-thread-1正在被执行,打印的值是:7
pool-1-thread-1正在被执行,打印的值是:8
pool-1-thread-1正在被执行,打印的值是:9
三、 缓冲队列BlockingQueue和自定义线程池ThreadPoolExecutor
  1. 缓冲队列BlockingQueue简介:

BlockingQueue是双缓冲队列。BlockingQueue内部使用两条队列,允许两个线程同时向队列一个存储,一个取出操作。在保证并发安全的同时,提高了队列的存取效率。

  1. 常用的几种BlockingQueue:

ArrayBlockingQueue(int i):规定大小的BlockingQueue,其构造必须指定大小。其所含的对象是FIFO顺序排序的。

LinkedBlockingQueue()或者(int i):大小不固定的BlockingQueue,若其构造时指定大小,生成的BlockingQueue有大小限制,不指定大小,其大小有Integer.MAX_VALUE来决定。其所含的对象是FIFO顺序排序的。

PriorityBlockingQueue()或者(int i):类似于LinkedBlockingQueue,但是其所含对象的排序不是FIFO,而是依据对象的自然顺序或者构造函数的Comparator决定。

SynchronizedQueue():特殊的BlockingQueue,对其的操作必须是放和取交替完成。

  1. 自定义线程池(ThreadPoolExecutor和BlockingQueue连用):

    自定义线程池,可以用ThreadPoolExecutor类创建,它有多个构造方法来创建线程池。

    常见的构造函数:ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue)

示例代码:

package com.gblfy.xe;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class ZiDingYiThreadPoolExecutor {public static class TempThread implements Runnable {@Overridepublic void run() {// 打印正在执行的缓存线程信息System.out.println(Thread.currentThread().getName() + "正在被执行");try {// sleep一秒保证3个任务在分别在3个线程上执行Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {// 创建数组型缓冲等待队列BlockingQueue<Runnable> bq = new ArrayBlockingQueue<Runnable>(10);// ThreadPoolExecutor:创建自定义线程池,池中保存的线程数为3,允许最大的线程数为6ThreadPoolExecutor tpe = new ThreadPoolExecutor(3, 6, 50, TimeUnit.MILLISECONDS, bq);// 创建3个任务Runnable t1 = new TempThread();Runnable t2 = new TempThread();Runnable t3 = new TempThread();Runnable t4 = new TempThread();Runnable t5 = new TempThread();Runnable t6 = new TempThread();// 3个任务在分别在3个线程上执行tpe.execute(t1);tpe.execute(t2);tpe.execute(t3);tpe.execute(t4);tpe.execute(t5);tpe.execute(t6);// 关闭自定义线程池tpe.shutdown();}
}

输出结果:

pool-1-thread-1正在被执行
pool-1-thread-2正在被执行
pool-1-thread-3正在被执行

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

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

相关文章

路径规划之 A* 算法

算法介绍 A*&#xff08;念做&#xff1a;A Star&#xff09;算法是一种很常用的路径查找和图形遍历算法。它有较好的性能和准确度。本文在讲解算法的同时也会提供Python语言的代码实现&#xff0c;并会借助matplotlib库动态的展示算法的运算过程。 A*算法最初发表于1968年&a…

王思聪究竟上了多少次热搜?

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 朱小五责编 | 阿秃王思聪又又又上了微博热搜——然而这次却不是关于娱乐圈。最近几天&#xff0c;王思聪与他的“限消令”接连登上热搜榜&#xff0c;引发吃瓜群众们广泛热议。知乎的段子手们也纷纷发挥自己的想象力。小五本…

2018年,自然语言处理很全的应用与合作

2018年见证了 NLP 许多新的应用发展。Elvis Saravia 是计算语言学专家&#xff0c;也是2019 计算语言学会年度大会北美分部的项目委员之一。他在一份报告中总结出&#xff0c;NLP 不仅在聊天机器人和机器学习中有所突破&#xff0c;也在医疗健康、金融、法律和广告等行业中有崭…

如何把springboot项目部署到tomcat上

文章目录一、 企业发布场景1. 首次发布2. 非首次发布3. 全量发布和增量发布概念和区别二、springboot部署tomcat2.1. 创建Web初始化类2.2. 修改打包方式2.3. 项目发布目录2.4. 启动tomcat2.5. 浏览器验证一、 企业发布场景 1. 首次发布 项目上线第一次会采用全量发布 【编译】…

OceanBase迁移服务:向分布式架构升级的直接路径

2019年1月4日&#xff0c;OceanBase迁移服务解决方案在ATEC城市峰会中正式发布。蚂蚁金服资深技术专家师文汇和技术专家韩谷悦共同分享了OceanBase迁移服务的重要特性和业务实践。 蚂蚁数据库架构的三代升级史 在过去的十多年时间里&#xff0c;蚂蚁在整个基础数据库架构上一…

linux中fdisk的参数,Linux fdisk命令参数及用法详解--Linux磁盘分区管理命令fdisk

fdisk 命令 linux磁盘分区管理用途&#xff1a;观察硬盘之实体使用情形与分割硬盘用。使用方法&#xff1a;一、在 console 上输入 fdisk -l /dev/sda &#xff0c;观察硬盘之实体使用情形。二、在 console 上输入 fdisk /dev/sda&#xff0c;可进入分割硬盘模式。1. 输入 m 显…

被嫌弃的互联网的 “一生”(上)

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 小灰责编 | 阿秃在人类的历史长河中&#xff0c;我们这一代人是最幸运的一代&#xff0c;因为我们生活在一个智慧飞扬的时代。这个时代最伟大的发明是什么&#xff1f;或许每个人心中都有不同的答案。在小灰看来&#xff0c;…

Mars 是什么、能做什么、如何做的——记 Mars 在 PyCon China 2018 上的分享

最近&#xff0c;在 PyCon China 2018 的北京主会场、成都和杭州分会场都分享了我们最新的工作 Mars&#xff0c;基于矩阵的统一计算框架。本文会以文字的形式对 PyCon 中国上的分享再进行一次阐述。 听到 Mars&#xff0c;很多第一次听说的同学都会灵魂三问&#xff1a;Mars …

Failed to bind properties under mybatis-plus.configuration.result-maps[0]

Failed to bind properties under mybatis-plus.configuration.incomplete-result-maps[0].assistant.configuration.mapped-statements[0].parameter-map.parameter-mappings[0] to org.apache.ibatis.mapping.ParameterMapping解决方案&#xff1a; 鉴于Spring Boot 2.2.0 和…

linux 协议错误,在linux客户机上:协议错误,Vagrant无法挂载同步的文件夹_vagrant_开发99编程知识库...

使用一個 Windows 主機和一個運行在in的Linux客戶機使用同步文件夾&#xff0c;我有一個奇怪的問題。在第一個引導( 或者在 vagrant destroy 之後) 中&#xff0c;項目文件夾掛載到/vagrant&#xff0c;但在停止並啟動虛擬機之後&#xff0c;文件夾將不會掛載。這是vagrant輸出…

MongoDB 如何使用内存?为什么内存满了?

最近接到多个MongoDB内存方面的线上case及社区问题咨询&#xff0c;主要集中在: 为什么我的 MongoDB 使用了 XX GB 内存&#xff1f;一个机器上部署多个 Mongod 实例/进程&#xff0c;WiredTiger cache 应该如何配置&#xff1f;MongoDB 是否应该使用 SWAP 空间来降低内存压力…

为什么要学Python 编程?(附Python学习路线)

为何程序员多数会选择 Python 作为入门级语言&#xff1f;在此&#xff0c;估计不少开发者都会予以反驳&#xff0c;自己明明就没有选择 Python&#xff0c;不能一概而论。下面&#xff0c;我们就用数据一窥如今最流行的编程语言。今年的 3 月份&#xff0c;国外招聘网站 Hacke…

“资源添加到Web应用程序[]的缓存中,因为在清除过期缓存条目后可用空间仍不足 - 请考虑增加缓存的最大空间”

解决办法&#xff1a; 在 /conf/context.xml 的 前添加以下内容&#xff1a; <Resources cachingAllowed"true" cacheMaxSize"100000" />

报告!这群阿里工程师在偷偷养猪

今天下午&#xff0c;期盼已久的阿里巴巴技术脱贫大会就要开始了。 很多人都知道&#xff0c;我们在1年前就投入100亿元人民币成立阿里巴巴脱贫基金。从教育到健康&#xff0c;再到女性、生态和电商扶贫&#xff0c;这五个方向分别由五位阿里合伙人直接牵头。 很多人不知道的…

七大新品集中亮相,腾讯云AI大数据全线升级!

近日腾讯云在北京举行大数据AI新品发布会。会上&#xff0c;腾讯云带来了在大数据与AI领域的最新研究成果&#xff0c;包括AI换脸甄别技术AntiFakes、腾讯星图以及企业画像平台等七大重磅新品&#xff0c;并对AI、大数据产品进行全线升级&#xff0c;致力于为用户带来更精细化的…

解决CentOS7本机时间与实际时间相差8小时的问题

查看当前日期时间&#xff1a; timedatectl删除原来的时间日期配置 rm -rf /etc/localtime链接指向新的时间日期配置 ln -sv /usr/share/zoneinfo/Universal /etc/localtime设置完成后查看当前时间日期&#xff1a; 如果不生效请重启 reboot

linux两个卷组可以合并,Linux系统中所有的逻辑卷必须属于同一个卷组()。

_债券收益率曲线的情况分别是( )商业银行进行流动性管理的方法有( )。眼见即脑见。MOST总线可以有睡眠模式直接切换到通电工作模式。在使用递归算法解决问题时&#xff0c;应满足以下两点&#xff1a;一是该问题能够被递归形式描述&#xff1b;二是【 】。()提问需要在理解篇章…

阿里开发者们的第15个感悟:做一款优秀大数据引擎,要找准重点解决的业务场景

2015年12月20日&#xff0c;云栖社区上线。2018年12月20日&#xff0c;云栖社区3岁。 阿里巴巴常说“晴天修屋顶”。 在我们看来&#xff0c;寒冬中&#xff0c;最值得投资的是学习&#xff0c;是增厚的知识储备。 所以社区特别制作了这个专辑——分享给开发者们20个弥足珍贵的…

解决vsftpd 读取目录列表失败的问题

文章目录1. 问题现象2. 解决方案(重启时效)3. 重启失效解决1. 问题现象 使用第三方FTP软件filezilla进行登陆&#xff0c;出现如下错误&#xff1a; 状态: 正在连接 192.168.1.6:21... 状态: 连接建立&#xff0c;等待欢迎消息... 响应: 220 (vsFTPd 2.2.2) 命令: …

阿里开发者们的第16个感悟:让阅读源码成为习惯

2015年12月20日&#xff0c;云栖社区上线。2018年12月20日&#xff0c;云栖社区3岁。 阿里巴巴常说“晴天修屋顶”。 在我们看来&#xff0c;寒冬中&#xff0c;最值得投资的是学习&#xff0c;是增厚的知识储备。 所以社区特别制作了这个专辑——分享给开发者们20个弥足珍贵的…