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

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

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的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 会停止该任务的后续执行,但不会停止线程池本身或其他任务的执行。如果需要处理任务执行中的异常,可以在任务内部进行捕获和处理。

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

在这里插入图片描述

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

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

相关文章

【QT】Ubuntu22.04 配置 QT6.5 LTS

【QT】Ubuntu22.04 配置 QT6.5 LTS 文章目录 【QT】Ubuntu22.04 配置 QT6.5 LTS1.注册QT Group的账号2.安装QT Creator3.启动QT Creator报错from 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin.4.运行QT的demoReference 1.注册QT Group的…

JAVASE基础语法(异常、常用类)

一、异常 1.1 什么是异常 异常就是指不正常。是指代码在运行过程中可能发生错误&#xff0c;导致程序无法正常运行。 package com.atguigu.exception;public class TestException {public static void main(String[] args) {int[] arr {1,2,3,4,5};System.out.println(&quo…

【nginx安装内置的http_image_filter_module】

背景 我的nginx源码目录为:/usr/mysoft/nginx-1.19.0/ nginx的目录为:/usr/local/nginx/sbin 命令:[rootVM-16-17-centos sbin]# cd /usr/sbin/ lrwxrwxrwx 1 root root 27 Apr 17 23:13 nginx -> /usr/local/nginx/sbin/nginx 进入源码目录 [rootVM-16-17-centos nginx-…

linux安装SSH

linux安装SSH 源码包链接 zlib&#xff1a;https://www.zlib.net/zlib_1.3.1.tar.gz openssl&#xff1a;https://www.openssl.org/source/openssl-3.3.0.tar.gz openssh&#xff1a;https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.7p1.tar.gz [rootloc…

【AI写作】未来科技趋势:揭秘DreamFusion的革新力量

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

数据库之数据库恢复技术思维导图+大纲笔记

大纲笔记&#xff1a; 事务的基本概念 事务 定义 用户定义的一个数据库操作系列&#xff0c;这些操作要么全做&#xff0c;要么全不做&#xff0c;是一个不可分割的基本单位 语句 BEGIN TRANSACTION 开始 COMMIT 提交&#xff0c;提交事务的所有操作 ROLLBACK 回滚&#xff0c…

Centos之yum安装好玩的命令

1.会动的小火车 我在root下使用的 yum install sl.x86_64sl2.figlet yum install figlet.x86_64figlet 55553.cowsay会说话 yum install cowsay

防火墙详细讲解

目录 介绍 防火墙的特征 防火墙的组成 介绍 防火墙&#xff08;firewall&#xff09;是指一种计算机硬件和软件的结合&#xff0c;将内部网和公众访问网&#xff08;如Internet&#xff09;分开的方法&#xff0c;它实际上是一种隔离技术。防火墙主要由服务访问规则、验证工…

leetcode刷题笔记——使用双指针处理链表问题

面试的时候经常碰见诸如获取倒数第k个元素&#xff0c;获取中间位置的元素&#xff0c;判断链表是否存在环&#xff0c;判断环的长度等和长度与位置有关的问题。这些问题都可以通过灵活运用双指针来解决 如果存在环&#xff0c;如何判断环的长度呢&#xff1f;方法是&#xff…

python数字验证码自动识别

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在网络上&#xff0c;许多网站和应用程序使用验证码&#xff08;Completely Automated Publ…

MYSQL 存储java.sql.Timestamp类型的数据时,mysql存储时间和java获取到的时间相差8小时

###JAVA JDBC驱动 com.mysql.cj.jdbc.DriverJDBC连接字符串 jdbc:mysql://127.0.0.1:3006/db?useUnicodetrue&characterEncodingUTF8&useLegacyDatetimeCodefalse&serverTimezoneUTCMySQL 时区 show global variables like “%time_zone%”; 问题分析 驱动…

汇编实现缓冲区溢出1

input: pushl %ebp # 保存帧指针 mov %esp, %ebp # 更新栈指针位置 pushl %ebx # 压入保护寄存器 subl $20, %esp # 通过减法运算在栈上分配 20 个字节的空间 leal -12(%ebp), %ebx # 计算缓冲区开始的位置&#xff0c;是 …

网络安全之SQL注入漏洞复现(中篇)(技术进阶)

目录 一&#xff0c;报错注入 二&#xff0c;布尔盲注 三&#xff0c;sleep延时盲注 四&#xff0c;DNSlogs 盲注 五&#xff0c;二次注入 六&#xff0c;堆叠注入 总结 一&#xff0c;报错注入 报错注入就是在错误信息中执行 sql 语句&#xff0c;利用网站的报错信息来带…

探索Linux系统:详尽指南教你查看系统信息

在Linux环境下工作时,了解系统的关键信息有助于我们更好地管理、诊断和优化系统性能。本文将详细介绍一系列实用命令,助你全面掌握Linux系统的硬件配置、软件版本、资源使用状况等重要细节。无论是日常运维还是故障排查,这些命令都是不可或缺的工具。让我们开始探索之旅吧!…

【奶奶看了都会】用 AI做猫咪剧情短片保姆级教程

大家这段时间在刷短视频的时候&#xff0c;是不是经常会刷到那种猫咪剧情短片&#xff0c;配合喵喵喵......的魔性背景音乐&#xff0c;让人看了非常上头。最近这类视频在抖音、视频号、小红书上非常火&#xff0c;今天就来教大家如何制作。 1.GPT4账号准备 我们用到的AI生图…

应用于智能装备制造,钡铼IOy系列模块展现其强大的灵活性和实用性

随着科技的飞速发展&#xff0c;智能制造已经成为工业4.0时代的核心驱动力。在此背景下&#xff0c;钡铼技术推出的IOy系列模块以其独特的设计、卓越的性能以及无可比拟的灵活性与实用性&#xff0c;在智能装备制造领域展现出了强大的技术优势和应用价值。 首先&#xff0c;钡…

HTTP与SOCKS-哪种协议更适合您的代理需求?

网络代理技术是我们日常使用网络时必不可少的一项技术&#xff0c;它可以为我们提供隐私保护和负载均衡的能力&#xff0c;从而保证我们的网络通信更加安全和顺畅。而其中最主流的两种协议就是HTTP和SOCKS。虽然它们都是用于网络代理的协议&#xff0c;但在实际应用中却存在着一…

python:根据旋转平移矩阵求取原始点云或者转换后点云

根据旋转平移矩阵求取原始点云或者转换后点云 原始点云进行旋转平移示例 1示例 2示例 3示例 4 根据转换后点云及转换矩阵求原始点云示例 1示例 2示例 3示例 4 原始点云进行旋转平移 转换前的点云可以表示为一个N行3列的矩阵&#xff0c;每一行代表一个点的坐标。我们定义一个旋…

Gitea:轻量级全功能DevSecOps平台的深度解析

Gitea&#xff1a;轻量级全功能DevSecOps平台的深度解析 在软件开发和版本控制领域&#xff0c;Gitea以其轻量级、开源和自托管的特点&#xff0c;逐渐受到越来越多个人开发者和小型团队的青睐。作为一个基于Go语言编写的Git服务软件&#xff0c;Gitea旨在提供一个易于安装、快…

儿童护眼落地灯哪个牌子好?值得买的五款大路灯分享

近年来&#xff0c;随着近视问题日益严重&#xff0c;消费者越来越倾向于选购能够优化照明环境、减轻眼部压力的护眼落地灯。然而&#xff0c;市场上的护眼落地灯品质良莠不齐&#xff0c;许多品牌为了追求低廉价格和扩大市场份额&#xff0c;不惜采取模仿甚至抄袭的方式&#…