【面试必会】线程池创建方式详解

最近面试问道了线程池的创建方式,这里出一篇文章记录下这一知识点!

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的ThreadFactory创建一个新线程。

线程池的创建主要依赖于java.util.concurrent包下的ExecutorServiceExecutors类。最近面试问到了这块,所以这篇文章我们将详细介绍几种常见的线程池创建方式。

在这里插入图片描述

FixedThreadPool

FixedThreadPool是一种固定大小的线程池。它的核心线程数和最大线程数都是创建时指定的数值,且不会变化。就算空闲,也不会回收线程,除非设置了allowCoreThreadTimeOut

举个栗子:我们创建一个固定大小为5的线程池,并提交10个任务。由于线程池的大小固定为5,因此这5个线程会并发执行,而剩下的任务会等待前面的任务完成后再执行。

代码如下:

	import java.util.concurrent.ExecutorService;  

	import java.util.concurrent.Executors;  

	  

	public class FixedThreadPoolDemo {  

	    public static void main(String[] args) {  

	        // 创建一个固定大小的线程池  

	        ExecutorService executorService = Executors.newFixedThreadPool(5);  

	  

	        for (int i = 0; i < 10; i++) {  

	            Runnable worker = new WorkerThread("" + i);  

	            executorService.execute(worker);  // 执行任务  

	        }  

	        executorService.shutdown();  // 关闭线程池  

	        while (!executorService.isTerminated()) {  

	        }  

	        System.out.println("所有任务已完成");  

	    }  

	}  

	  

	class WorkerThread implements Runnable {  

	    private String command;  

	  

	    public WorkerThread(String s) {  

	        this.command = s;  

	    }  

	  

	    @Override  

	    public void run() {  

	        System.out.println(Thread.currentThread().getName() + " 开始. 命令 = " + command);  

	        processCommand();  

	        System.out.println(Thread.currentThread().getName() + " 结束.");  

	    }  

	  

	    private void processCommand() {  

	        try {  

	            Thread.sleep(5000);  

	        } catch (InterruptedException e) {  

	            e.printStackTrace();  

	        }  

	    }  

	}

CachedThreadPool

CachedThreadPool是一种缓存线程池,它的线程数量是不定的,可以说是几乎无限的。当提交一个任务时,如果线程池中有空闲线程,则立即执行;如果没有,则创建一个新线程执行。当线程空闲超过60秒,则自动回收。

举个栗子:

	import java.util.concurrent.ExecutorService;  

	import java.util.concurrent.Executors;  

	  

	public class CachedThreadPoolDemo {  

	    public static void main(String[] args) {  

	        // 创建一个可缓存的线程池  

	        ExecutorService executorService = Executors.newCachedThreadPool();  

	  

	        for (int i = 0; i < 10; i++) {  

	            Runnable worker = new WorkerThread("" + i);  

	            executorService.execute(worker);  // 执行任务  

	        }  

	        executorService.shutdown();  // 关闭线程池  

	        while (!executorService.isTerminated()) {  

	        }  

	        System.out.println("所有任务已完成");  

	    }  

	}

CachedThreadPool`适合执行大量的耗时较少的任务,如Web服务器。

SingleThreadExecutor

SingleThreadExecutor是一个单线程的Executor,它使用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。

	import java.util.concurrent.ExecutorService;  

	import java.util.concurrent.Executors;  

	  

	public class SingleThreadExecutorDemo {  

	    public static void main(String[] args) {  

	        // 创建一个单线程的线程池  

	        ExecutorService executorService = Executors.newSingleThreadExecutor();  

	  

	        for (int i = 0; i < 10; i++) {  

	            Runnable worker = new WorkerThread("" + i);  

	            executorService.execute(worker);  // 执行任务  

	        }  

	        executorService.shutdown();  // 关闭线程池  

	        while (!executorService.isTerminated()) {  

	        }  

	        System.out.println("所有任务已完成");  

	    }  

	}

SingleThreadExecutor中,由于只有一个线程,因此任务会按照提交的顺序一个接一个地执行,不会出现并发的情况

ScheduledThreadPool

ScheduledThreadPool 是 Java 并发包 java.util.concurrent 中提供的一个线程池实现,它用于在给定的延迟后运行命令,或者定期地执行命令。ScheduledThreadPool 的主要特点是能够处理需要定时执行或周期性执行的任务

举个栗子:

	import java.util.concurrent.Executors;  

	import java.util.concurrent.ScheduledExecutorService;  

	import java.util.concurrent.TimeUnit;  

	  

	public class ScheduledThreadPoolDemo {  

	    public static void main(String[] args) {  

	        // 创建一个ScheduledThreadPool,包含3个核心线程  

	        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);  

	  

	        // 提交一个Runnable任务,在延迟2秒后执行  

	        scheduledExecutorService.schedule(new RunnableTask("一次性任务"), 2, TimeUnit.SECONDS);  

	  

	        // 提交一个Runnable任务,初始延迟2秒,之后每隔1秒执行一次  

	        scheduledExecutorService.scheduleAtFixedRate(new RunnableTask("周期性任务"), 2, 1, TimeUnit.SECONDS);  

	  

	        // 通常我们需要在程序结束时关闭线程池  

	        // scheduledExecutorService.shutdown();  

	    }  

	  

	    static class RunnableTask implements Runnable {  

	        private String command;  

	  

	        public RunnableTask(String command) {  

	            this.command = command;  

	        }  

	  

	        @Override  

	        public void run() {  

	            System.out.println(Thread.currentThread().getName() + " 开始执行命令: " + command + " at " + System.currentTimeMillis());  

	        }  

	    }  

	}

我们创建了一个 ScheduledThreadPool,它包含3个核心线程。然后,我们提交了两个任务:

  1. 一个是一次性任务,它在提交后的2秒后开始执行。
  2. 另一个是周期性任务,它在提交后的2秒开始执行,然后每隔1秒执行一次。

除了以上的用法
ScheduledExecutorService 提供了几个用于定时执行任务的方法:

  • schedule(Runnable command, long delay, TimeUnit unit):在给定延迟后运行命令一次。
  • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit):初始延迟后开始首次执行,然后随后每隔固定周期执行一次。
  • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit):初始延迟后开始首次执行,然后每次执行完毕后等待固定延迟再次执行。

如果任务执行过程中抛出异常,那么 ScheduledThreadPool 会停止该任务的后续执行,但不会停止线程池本身或其他任务的执行。如果需要处理任务执行中的异常,可以在任务内部进行捕获和处理。

以上就是创建线程池的几种方式,本篇文章到此结束,谢谢大家的观看!

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

报名照片10k怎么处理?教你几个方法

现在在每年的事业单位考公的时候&#xff0c;大家都会在网上报名提交个人信息&#xff0c;其中有一项就是需要上传我们的考试证件照&#xff0c;平台通常会要求照片大小为10kb以下&#xff0c;那么如何将过大的图片压缩到10kb呢?本文将介绍如何处理这一问题&#xff0c;让您轻…

STM32 HAL库F103系列之ADC实验(一)

ADC工作原理&#xff1a; 1、输入通道&#xff1a; 2、转换序列&#xff1a; A/D转换被组织为两组&#xff1a;规则组&#xff08;常规转换组&#xff09;和注入组&#xff08;注入转换组&#xff09; 规则组最多可以有16个转换&#xff0c;注入组最多有4个转换 规则组和注入…

redis7安装与配置

一、下载 通过 redis官网 或者 redis中文网 下载。 以下是 redis 相关文档资料链接&#xff1a; redis源码地址 redis在线测试 redis命令参考 redis中文文档 历史发布版本的源码地址 二、版本命名规则 Redis从发布到现在&#xff0c;已经有十余年的时光了&#xff0c;…

修改npm源--多种方式

2024年&#xff0c;1月22日 npm.taobao.org 域名证书已到期下线。 重置官方源 npm config set registry https://registry.npmjs.org/ 淘宝源&#xff0c;使用最新版&#xff0c;旧版停止了 npm config set registry https://registry.npmmirror.com 查看当前镜像源 npm …

跨越未知,拥抱挑战——新征程

在浩瀚的IT领域里&#xff0c;每一位开发工程师都如同一位探险家&#xff0c;不断地探索、挑战和成长。作为一名新入职的Java开发工程师&#xff0c;我面临着全新的技术栈和业务领域&#xff0c;这是一次跨越未知的征程&#xff0c;也是一次自我提升的机会。 新入职 初入公司…

基于Springboot的网课管理系统

基于SpringbootVue的网课管理系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 课程表 论坛交流 学校公告 后端 学生管理 教师管理 班级管理 课程分类管理…

【AI】如何让局域网PC能够访问langchain框架的AI服务

【背景】 在单位内部成功运行了langchain服务&#xff0c;但是发现本地可以用默认8000端口访问&#xff0c;但是局域网内其它机器却无法访问服务页面。 【分析】 首先查看项目文件夹中的server.py。由于这个server.py的存在&#xff0c;我一开始以为langchain整套框架的服务…

丙级资质升级乙级实操:河南灌溉排涝项目所需材料清单

丙级资质升级乙级实操&#xff1a;河南灌溉排涝项目所需材料清单 在河南灌溉排涝项目中&#xff0c;从丙级资质升级到乙级资质是一个重要且复杂的过程。为了成功完成这一过程&#xff0c;需要准备一系列详尽且符合规定的材料。以下是针对此实操所需的关键材料清单&#xff1a;…

服务器raid卡,守护数据安全,赋能新质生产力

RAID卡&#xff0c;全称为独立冗余磁盘阵列卡&#xff0c;在数据中心、服务器、网络存储等领域得到广泛应用&#xff0c;RAID卡通过不同的RAID级别实现数据容错和冗余。例如&#xff0c;RAID 0主要适用于需要高速数据传输但对数据安全要求不高的场景&#xff0c;如数据的缓存&a…

设计模式之观察者模式(优先使用对象组合的原则)的C++实现

观察者模式又称订阅者发布者模式&#xff0c;本篇介绍主要是利用对象组合大于类继承的设计模式原则实现订阅发布模式&#xff0c;这种设计的优点是想订阅数据的类不需要继承订阅者类的抽象类&#xff0c;减少了一层类的继承&#xff1b;当然&#xff0c;具体情况需要可根据需求…

[GXYCTF2019]BabyUpload-BUUTF

题&#xff1a; 步骤&#xff08;先上传木马&#xff0c;在上传.htaccess&#xff09; 准备工作 他过滤了<? ,ph等 准备&#xff1a;一句话木马&#xff0c;.htaccess文件 .htaccess SetHandler application/x-httpd-php //解析为php文件 muma1.jpg<script languag…

【vue2+onlyoffice】基础预览demo运行+问题解决

之前其实写过Onlyoffice的使用&#xff0c;但是写得不太完整&#xff0c;这次补充下。 一、OnlyOffice简介 ONLYOFFICE&#xff0c;是一个包含常用办公套件&#xff0c;Word 、Excel、PPT大办公套件搬到了云端&#xff0c;只需要一个浏览器即可以在线使用 Office 的各种功能。…

HOOPS Commuicator:基于Web的交互式2D/3D图形轻量化引擎

在当前数字化时代&#xff0c;Web基础的3D应用程序正在成为行业标准&#xff0c;尤其是在工程和制造领域。Tech Soft 3D公司旗下的HOOPS Communicator正是针对这一需求设计的高级解决方案&#xff0c;提供了一套全面的工具&#xff0c;旨在帮助开发者构建复杂的3D工程应用程序。…

3. 无重复字符的最长子串/438. 找到字符串中所有字母异位词/560. 和为 K 的子数组

3. 无重复字符的最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。 思路&#xff1a;想象一下我们…

Spring MVC和Spring Boot

上节已经提到过请求&#xff0c;这次梳理响应。 响应 响应基本上都要被Controller所托管&#xff0c;告诉Spring帮我们管理这个代码&#xff0c;我们在后面需要访问时&#xff0c;才可以进行访问&#xff0c;否则将会报错。并且其是由RestController分离出来的&#xff0c;Re…

免杀技术之白加黑的攻击防御

一、介绍 1. 什么是白加黑 通俗的讲白加黑中的白就是指被杀软列入到可信任列表中的文件。比如说微软自带的系统文件或者一些有有效证书签名的文件,什么是微软文件&#xff0c;或者什么是有效签名文件在后面我们会提到他的辨别方法。黑就是指我们自己的文件&#xff0c;没有有…

allegro输出正反面bom

不是前面两条命令&#xff0c;而是component report

Scrapy

【 一 】Scrapy介绍 【0】前言 Scrapy知识预备 ​ 爬虫毕竟是在网页里面抓取数据的,因此前端那些东西没学过也要稍微懂点。HTML、CSS简单的语法,Xpath、正则表达式等等,需要有一些简单的基础。 ​ Scrapy一个开源和协作的框架,其最初是为了页面抓取(更确切来说,网络抓…

Day26: Redis入门、开发点赞功能、开发我收到的赞的功能、重构点赞功能、开发关注、取消关注、开发关注列表、粉丝列表、重构登录功能

Redis入门 简介 Redis是NoSQL数据库&#xff08;Not only SQL&#xff09;值支持多种数据结构&#xff08;key都是string&#xff09;&#xff1a;字符串、哈希、列表、集合、有序集合把数据存在内存中&#xff0c;速度惊人&#xff1b;同时也可以讲数据快照&#xff08;数据…