Java 面试笔记 | Java 基础:线程池

前言

在日常的工作学习生活中,用一种好的方法去学习,可以更加有效,比如费曼学习法将学到的知识用自己的组织的语言表达出来,如果能够清晰明白的向别人解释清楚,那么就说明你是真的懂了,学会了。如果不能够很好的表述出来,或者被别人问倒了,那说明有不懂的细节存在,需要再次对所学的知识进行巩固。所以在平时学习的时候,可以多与别人交流,将所学的知识讲述给别人听,当没有太多人可以交流的时候,也可以通过向自己提问题的方式,看看自己能否真正的回答好这些问题,或者通过写文章,将所学的知识用自己的话写出来,这也是检验自己学习成果的一种方法。发现自己过去存在的一个比较差的习惯,在学习相关知识时,只以摘抄式的方式记笔记,而缺少复盘,没有融入自己的思考,浮于表面,当做题或者面试时接受别人的提问时,问题立马就出现了,自己没法解决这些问题,在短时间内没能很好的解释这个知识点,心里只有一些相对模糊的概念。所以什么才是真正的懂得?那就是需要看清事物与问题的本质,将所学真正的知识进行内化。在准备面试的时候也是一样,可以从不同的角度多问自己几个问题,明白了底层的逻辑和原理,记忆起来也会更加简单。这篇文章会介绍线程池相关的一些知识,从以下几个方面进行探讨:

  • 为什么要使用线程池(线程池解决了什么问题)
  • JDK中线程池的设计思想,运行流程
  • 深入了解底层源码的一些实现细节

理解线程池所要解决的问题

说到多线程,常常就与处理多个任务相关联,所以从多线程的使用场景说起,更深的层次还要理解什么是进程、线程和线程。

  • 计算机如何同时处理多个任务?

计算机如何在同一时间处理多个任务呢?在 Java 当中,可以通过创建多个线程实现。系统为每个任务都创建一个线程,将不同的任务交由不同的线程进行处理,这样就实现了同一时间处理多个任务,相当于把不同的任务分配给不同的人来处理解决。

  • 线程池的概念?主要用于解决什么问题

线程池主要用于解决线程复用的问题。如果为每个任务都分配一个线程来处理,那么当任务量很大时,就需要创建大量的线程来处理这些任务。这种方案的问题是:一方面,系统是没办法无限制的创建线程的,操作系统能够创建的线程的数量是有最大值限制的,另一方面,如果任务时多时少,那么就需要频繁的创建和销毁线程;而创建、销毁都是需要一定的系统开销的。所以就有了线程池,大致的思想如下:系统事先创建好一定数量的线程,放到一个池子里面,当一个任务过来,就从池子里拿出一个线程来处理这个任务,处理完后,在将线程放回池子当中。如果任务太多,池子里已经没有空闲的线程来处理这些任务了,就将这些没办法即时处理的任务放入到一个等待队列当中,等池子里有空闲的线程了,再从队列中取出任务进行处理,这样就实现了线程的复用,避免频繁创建和销毁线程所带来的系统开销。具体的设计思想与上面的所说的有所偏差,我们来看看 JDK 当中是如何设计和实现一个线程池的。

  • 说说 JDK 中线程池的设计思想与运行流程?

ThreadPoolExecutorJDK 中线程池的实现类,顶层接口 Executor 定义了一个执行任务的抽象方法,ExecutorService 接口在 Executor 接口的基础上,规范了线程池需要有的一些功能:比如关闭线程池(关闭后线程池不能再接收新的任务)、线程池的状态(是否关闭)、提交异步任务等。

image.png

  • 问题:1、线程池是怎么定义的,线程是如何存储在池子当中的?

JDK 当中定义了一个集合HashSet<Worker> 用来维护被创建出来的线程对象。

线程池状态( rs :标记线程池的状态,根据状态量来控制线程池应该做什么。

活跃线程数(wc :标识现在池子里的活跃线程数,以此判断要创建核心线程还是非核心线程。

JDK 中用一个 Integer 变量(ctl)来保存线程池状态和活跃线程数。通过对这个变量的与、或、非等计算,可以计算我们想要的一些数据,如通过:runStateOf 方法获取当前线程池的状态、workerCountOf 方法获取活跃线程数。阻塞队列通过workQueue.offer(command) 往任务队列当中添加任务,如果队列满了,任务无法添加到对垒当中,会返 false

  • 解释一下 JDK 线程池的构造函数参数?这些参数的作用?
    • 核心线程数:核心线程&非核心线程的概念:核心线程默认情况下会常驻于线程池当中(即使没有执行什么任务),非核心线程如果长时间闲置便会被销毁(相当于临时工,所以后面又有个非核心线程空闲的存活时间,以及存活的时间单位)。
    • 最大线程数:核心线程的数量+非核心线程的数量。
    • 非核心线程空闲时的存活时间、以及存活的时间单位。
    • 任务队列:用来暂存来不及处理的任务,线程池当中没有可以用来处理任务的线程了,那么这时候就会先将任务放入到队列当中,等待有空闲的线程来进行处理。
    • 线程池工厂:用来统一管理和创建线程。
    • 拒绝处理策略:任务无法进行处理了(任务队列满了,线程达到最大线程数,此时不允许再创建线程来处理任务了),就会执行任务拒绝处理策略。
  • 线程池的运行流程

初始时,线程池的当中的线程是空的,当一个任务过来,交由 execute 方法执行,会判断当前线程池当中的工作线程数是否小于核心线程数,优先去创建核心线程。如果核心线程已满,就会将任务暂存到任务队列当中,如果任务队列也满了,就会去创建非核心线程,如果添加非核心线程失败,就会执行任务拒绝处理策略。这里需要记住非核心线程是在队列满了之后才创建的。

  • 拒绝处理的策略有哪些?
  • 丢弃任务并抛出拒绝处理的异常信息
  • 丢弃新来的任务,但是不抛出异常
  • 丢弃队列头部(最旧的)的任务,然后重新尝试执行程序(如果再次失败,重复此过程)。
  • 直接在调用线程中执行被拒绝的任务
  • 应用到的设计模式

策略接口:RejectedExecutionHandler

具体的拒绝策略:AbortPolicyDiscardPolicyDiscardOldestPolicy、`CallerRunsPolicy

线程池使用的默认任务拒绝策略是:丢弃任务并抛出拒绝处理的异常信息:

private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,threadFactory, defaultHandler);

参考链接

  • JDK ThreadPoolExecutor核心原理与实践 - vivo互联网技术 - 博客园
  • https://redspider.gitbook.io/concurrent

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

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

相关文章

SQL EXISTS 关键字的使用与理解

SQL EXISTS 关键字的使用与理解 SQL&#xff08;Structured Query Language&#xff09;是一种用于管理关系数据库管理系统&#xff08;RDBMS&#xff09;的标准编程语言。在SQL中&#xff0c;EXISTS关键字是一个逻辑运算符&#xff0c;用于检查子查询中是否存在至少一行数据。…

运行时库链接方式实践指南(MT、MD、MTd、MDd)

前言 笔者曾经编译一个库提供给使用者&#xff0c;提供库后发现由于运行时库连接方式不一致&#xff0c;导致使用者无法连接笔者提供的库。另一方面&#xff0c;理解和选择正确的运行时链接方式对于构建高效、可靠的应用程序至关重要。 因此&#xff0c;本文将展开运行时库的基…

基于 Spring Boot 与 WebSocket 实现实时车位管理与状态更新

本章将深入探讨停车场管理系统中的技术难题&#xff0c;并提供基于Spring Boot 3.x的解决方案。每篇文章集中解决一个实际的技术难题&#xff0c;涵盖车位管理、自动识别、数据监控、系统优化等多方面的问题。通过详细的剖析和实际案例与代码示例&#xff0c;帮助开发者应对挑战…

新手教学系列——“笑看”单元测试(pytest)

探索单元测试的必要性 你是否曾经思考过,当前的业务场景是否真的需要单元测试?我们每个人负责的模块是否也需要单元测试?什么阻碍了我们进行单元测试呢?时间紧,任务重,还要写测试?这些都是我们在开发过程中常见的问题。假设我们有一个计划开发一周的项目,让我们看看有…

[Redis]事务

Redis事务 Redis 事务提供了一种将多个命令请求打包的功能。然后&#xff0c;再按顺序执行打包的所有命令&#xff0c;并且不会被中途打断。 但是&#xff0c;事务中的每条命令都会与 Redis 服务器进行网络交互&#xff0c;比较浪费资源 所以&#xff0c;日常开发中不建议使…

深入探究:Kylin Cube构建时间的影响因素与优化策略

引言 Apache Kylin是一个开源的分布式分析引擎&#xff0c;旨在为Hadoop和Spark平台上的大数据提供快速的SQL查询能力。Kylin通过预计算技术&#xff0c;将数据预先聚合并存储在HBase中&#xff0c;从而实现对大数据集的亚秒级查询响应。Cube是Kylin中的核心概念&#xff0c;它…

工控 UI 风格美轮美奂

工控 UI 风格美轮美奂

出现apimswincrtruntimel110dll丢失不兼容的情况如何快速修复?

在使用多种软件应用的过程中&#xff0c;我们时常面对一些技术难题&#xff0c;其中动态链接库&#xff08;DLL&#xff09;文件的兼容性问题尤为常见。这些问题不仅可能干扰应用程序的平稳运行&#xff0c;还有可能危及整个操作系统的稳定。例如&#xff0c;“api-ms-win-crt-…

九、(正点原子)Linux定时器

一、Linux中断简介 1、中断号 每个中断都有一个中断号&#xff0c;通过中断号即可区分不同的中断&#xff0c;有的资料也把中断号叫做中断线。在 Linux 内核中使用一个 int 变量表示中断号。在Linux中&#xff0c;我们可以使用已经编写好的API函数来申请中断号&#xff0c;定义…

使用轻量级虚拟桌面基础架构 (VDI)进行安全快速的访问,实现混合云环境的远程工作

使用轻量级虚拟桌面基础架构 &#xff08;VDI&#xff09;进行安全快速的访问&#xff0c;实现混合云环境的远程工作 许多企业都存在混合计算基础结构&#xff0c;其中某些应用程序已迁移到云&#xff0c;另外一些部署在数据中心。 现代虚拟桌面基础架构 &#xff08;VDI&…

波导尺寸与有效折射率之间的关系

波导尺寸与有效折射率之间的关系 正文正文 我们知道,波导的折射率是波导材料本身的一种特性,这里我们以 S i Si Si 和 S i O 2 SiO_2

【C/C++】this指针的概念和作用

目录 一、this指针的概念 二、this指针的作用 2.1 访问当前对象的成员 2.2 返回对象本身 2.3 区分对象 2.4 在构造函数和析构函数中 2.5 在类的内部调用其他成员函数 2.6 作为参数传递 三、this指针使用 3.1 this指针的使用 3.2 C++ 中this指针使用 一、this…

一个土木工程专业背景的开发者,讲述开源带给他的力量

在前段时间我们举办的“TDengine Open Day”第一季技术沙龙中&#xff0c;TDengine 应用研发高级工程师谭雪峰进行的“开源之路&#xff1a;程序员的成长与探索”主题分享获得了众多参会者的好评。谭雪峰从自身独特的职业发展经历出发&#xff0c;分享了自己在开源领域的种种收…

【华为OD机试】上班之路/是否能到达公司(C++/Java/Python)

题目 题目描述 Jungle 生活在美丽的蓝鲸城,大马路都是方方正正,但是每天马路的封闭情况都不一样。 地图由以下元素组成: 1)”.” — 空地,可以达到; 2)”*” — 路障,不可达到; 3)”S” — Jungle的家; 4)”T” — 公司. 其中我们会限制_Jungle_拐弯的次数,同时_Jung…

前端开发之webpack

安装与入门超详细&#xff01;webpack入门教程(一)-腾讯云开发者社区-腾讯云

B端系统:增删改查中的新建(增)页面如何设计体验更爽。

在B系统中&#xff0c;增删改查是最基本、最常用的功能之一。这四个操作对于系统的正常运行和数据管理至关重要。其中&#xff0c;新增&#xff08;新建&#xff09;页面的设计尤为关键&#xff0c;因为它直接影响着用户体验和系统功能的完整性。 一、新增&#xff08;新建&…

程序的“通用性”与“过度设计”的困境及具体解决方案

程序的“通用性”与“过度设计”的困境及具体解决方案 在软件工程的实践中&#xff0c;追求程序的“通用性”与避免“过度设计”之间的平衡是一个挑战。下面将针对这一困境&#xff0c;给出具体的解决方案。 一、明确需求与目标 1. 需求分析与优先级排序 在项目开始之前&am…

Windows查看系统激活状态

按 WinR 键启动运行程序&#xff0c;然后输入以下任意命令&#xff1a; slmgr.vbs -xpr slmgr.vbs -div

项目实训-vue(十七)

项目实训-vue&#xff08;十七&#xff09; 文章目录 项目实训-vue&#xff08;十七&#xff09;1.概述2.问诊类型3.问诊时间统计4.看诊时间统计 1.概述 本篇博客将记录我在数据统计页面中的工作。因为项目并未实际运行&#xff0c;因此我们拟定了一些数据&#xff0c;并构建了…

DIY 智能门禁:用 ESP32 RFID 打造安全便捷的家居体验 (附代码)

一、系统概述 本项目旨在使用 ESP32 微控制器和 RFID 技术构建一个安全可靠的门禁系统。该系统利用 RFID 卡进行身份验证&#xff0c;通过读取卡内存储的唯一 ID&#xff0c;判断用户权限并控制门锁的开关。ESP32 强大的 Wi-Fi 功能还能实现远程监控和管理&#xff0c;方便用户…