当前位置: 首页 > news >正文

多线程常见面试题

1.Java线程池有哪些核心参数,分别有什么的作用?

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(        

                 8,        

                16,        

                60,        

                TimeUnit.SECONDS,        

                new ArrayBlockingQueue<Runnable>(1024),                         Executors.defaultThreadFactory(),        

                new ThreadPoolExecutor.CallerRunsPolicy() );

构造方法最多的是7个参数;

(1)int corePoolSize, 线程池中的核心线程数量 allowCoreThreadTimeOut;允许核心线程超时销毁; boolean prestartCoreThread(),初始化一个核心线程; int prestartAllCoreThreads(),初始化所有核心线程;

(2)int maximumPoolSize, 线程池中允许的最大线程数,当核心线程全部繁忙且任务队列存满之后,线程池会临时追加线程,直到总线程数达到maximumPoolSize这个上限;

(3)long keepAliveTime, 线程空闲超时时间,如果一个线程处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁;

(4)TimeUnit unit, keepAliveTime的时间单位 (天、小时、分、秒......);

(5)BlockingQueue<Runnable> workQueue, 任务队列,当核心线程全部繁忙时,任务存放到该任务队列中,等待被核心线程来执行;

(6)ThreadFactory threadFactory, 线程工厂,用于创建线程,一般采用默认的线程工厂即可,也可以自定义实现;

Executors.defaultThreadFactory(),

Executors.privilegedThreadFactory(),(过时)

(7)RejectedExecutionHandler handler, 拒绝策略(饱和策略),当任务太多来不及处理时,如何“拒绝”任务?

1、核心线程corePoolSize正在执行任务;

2、线程池的任务队列workQueue已满;

3、线程池中的线程数达到maximumPoolSize时;

就需要“拒绝”掉新提交过来的任务;

2.线程池有哪些拒绝策略? 

JDK提供了4种内置的拒绝策略:

AbortPolicy、

CallerRunsPolicy、

DiscardOldestPolicy、

DiscardPolicy;

1、AbortPolicy(默认):丢弃任务并抛出RejectedExecutionException异常,这是默认的拒绝策略;

2、DiscardPolicy:直接丢弃任务,不抛出异常,没有任何提示;

3、DiscardOldestPolicy:丢弃任务队列中靠最前的任务,当前提交的任务不会丢弃;

4、CallerRunsPolicy: 交由任务的调用线程(提交任务的线程)来执行当前任务;

除了上面的四种拒绝策略,还可以通过实现RejectedExecutionHandler接口,实现自定义的拒绝策略; 

3.说一说线程池的执行流程? 

 当提交一个新任务到线程池时,具体的执行流程如下:

1. 当我们提交任务,线程池会根据corePoolSize大小创建线程来执行任务;

2. 当任务的数量超过corePoolSize数量,后续的任务将会进入阻塞队列阻塞排队;

3. 当阻塞队列也满了之后,那么将会继续创建(maximumPoolSize-corePoolSize)个数量的线程来执行任务,如果任务处理完成,maximumPoolSize-corePoolSize个额外创建的线程等待 keepAliveTime之后被自动销毁;

4. 如果达到maximumPoolSize,阻塞队列还是满的状态,那么将根据不同的拒绝策略进行拒绝处理;

4.线程池核心线程数怎么设置呢? 

Ncpu = cpu的核心数 ,Ucpu = cpu的使用率(在0~1之间)

W = 线程等待时间,C = 线程计算时间

举例:

8 * 100% * (1+60/40) = 20

8 * 100% * (1+80/20) = 40 

任务分为CPU密集型和IO密集型

CPU密集型

        线程数 = CPU核心数 + 1; 这种任务主要是消耗CPU资源, 比如像加解密、压缩、计算等一系列需要大量耗费 CPU 资源的任务; +1,比 CPU 核心数多出来的一个线程是为了防止线程偶发的缺页中断,或者其它原因导致的任务暂停而带来的影响。一旦任务暂停,CPU 就会处于空闲状态,而在这种情况下多出来的一个线程就可以充分利用 CPU 的空闲时间; 

IO密集型

        线程数 = CPU核心数 * 2; 这种任务会有大部分时间在进行IO操作,比如像MySQL数据库、文件读写、网络通信等任务,这类任务不会特别消耗CPU资源,但是IO操作比较耗时,会占用比较多时间; 线程在处理IO的时间段内不会占用CPU,这时就可以将CPU交出给其它线程使用,因此在IO密集型任务的应用中,可以多配置一些线程;

基本原则:

1、线程执行时间越多,就需要越少的线程;

2、线程等待时间越多,就需要越多的线程;

以上理论参考依据,实际项目中建议在本地或者测试环境进行压测多次调整线程池大小,找到相对理想的值大小;


http://www.mrgr.cn/news/22236.html

相关文章:

  • 【C++】手把手教你看懂的 STL map 详解(超详细解析,小白一看就懂!!)
  • LeetCode HOT100系列题解之数组中的第K个最大元素(7/100)
  • Java零基础入门--自动拆箱
  • 数据库的配置1:Mysql服务端的下载与配置
  • JavaWeb【day11】--(SpringBootWeb案例)
  • Redis 持久化
  • 笔记整理—内核!启动!—kernel部分(1)从汇编阶段到start_kernel
  • C语言手撕归并——递归与非递归实现(附动画及源码)
  • MATLAB基础语法知识
  • 秋招想要过在线测评,这些知识必须刷
  • Spring05——注解开发定义bean、Spring纯注解开发模式
  • Pipeline流水线通过git拉取Jenkinsfile报错 error: RPC failed; result=22, HTTP code = 404
  • 小红书自热矩阵:低成本创业神器,轻松引流实现财富自由
  • DPDK基础入门(六):从PCIe事务的角度看包处理
  • 01背包问题和完全背包问题
  • dubbo 服务消费原理分析之服务目录
  • Java 中常用内置接口函数
  • 【MySQL】MySQL中表的增删改查——(基础篇)(超详解)
  • 2025年25届最新:如何用Java SpringBoot搭建公考学习平台?
  • CTK框架(三): 插件的安装