第二季:9.线程池用过吗?生产上你如何设置合理参数【Java面试题】

简介: 第二季:9.线程池用过吗?生产上你如何设置合理参数【Java面试题】

【Java面试题】)

前言


2022 10/11 19:46

路漫漫其修远兮,吾将上下而求索


本文是根据尚硅谷学习所做笔记

仅供学习交流使用,转载注明出处


推荐

尚硅谷Java大厂面试题第2季,面试必刷,跳槽大厂神器

第二季大佬总结

9.线程池用过吗?生产上你如何设置合理参数

说明

本文目录前是相关视频的名字和具体视频中思维导图的名字

题目

9.线程池用过吗?生产上你如何设置合理参数

51 线程池的4种拒绝策略理论简介

线程池的拒绝策略你谈谈

是什么

等待队列也已经排满了,再也塞不下新任务了

同时,

线程池中的max线程也达到了,无法继续为新任务服务。
这时候我们就需要拒绝策略机制合理的处理这个问题。

JDK内置的拒绝策略

  • AbortPolicy(默认):直接抛出 RejectedExecutionException异常阻止系统正常运行。
  • CallerRunsPolicy:"调用者运行"一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量
  • DiscardoldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务。
  • DiscardPolicy:直接丢弃任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种方案。

以上内置拒绝策略均实现了RejectedExecutionHandler 接口

52 线程池实际中使用哪一个

×你在工作中单一的固定数的/可变的三种创建线程池的方法,你用那个多?超级大坑

答案是一个都不用,我们生产上只能使用自定义的

Executors中JDK已经给你提供了,为什么不用?

阿里巴巴Java开发手册
3.【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

说明: 使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存:者“过度切换”的问题。


4.【强制】线程池不允许使用Executors 去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

说明: Executors返回的线程池对象的弊端如下:

1.FixedThreadPool和singleThreadPool:

允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。

2.cachedThreadPool和 scheduledThreadPool:

允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

53 线程池的手写改造和拒绝策略

你在工作中是如何使用线程池的。是否自定义过线程池使

Case

package threadpool8;
import java.util.concurrent.*;
/**
 * @author CSDN@日星月云
 * @date 2022/10/10 21:26
 * 第4种获得使用Java多线程的方式,线程池
 */
public class MyThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService threadPool=new ThreadPoolExecutor(
                2,
                5,
                1L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardPolicy());
        try {
            //模拟10个用户开办理业务,每一个用户就是一个来自外面的请求线程
            for (int i = 1; i <= 9; i++) {
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"\t 办理业务");
                    //tsleep
                    try{ TimeUnit.MILLISECONDS.sleep(200); }catch (InterruptedException e){ e.printStackTrace(); }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
    /**
     * AbortPolicy          异常阻止系统正常运行      RejectedExecutionException
     * CallerRunsPolicy     任务回退到调用者         main  办理业务
     * DiscardOldestPolicy  抛弃队列中等待最久的任务
     * DiscardPolicy        直接丢弃任务            8个,丢一个
     */
    public static void threadPoolInit() {
    //...     
  }
}

54 线程池配置合理线程数

合理配置线程池你是如何考虑的?

CPU密集型

CPU密集的意思是该任务需要大量的运算,而没有阻塞,CPU一直全速运行。CPU密集任务只有在真正的多核CPU上才可能得到加速(通过多线程),


而在单核CPU上:(悲剧吧?),无论你开几个模拟的多线程该任务都不可能得到加速,因为CPU总的运算能力就那些。


CPU密集型任务配置尽可能少的线程数量:

一般公式:CPU核数+1个线程的线程池

IO密集型

1

由于IO密集型任务线程并不是一直在执行任务,则应配置尽可能多的线程,如CPU核数 * 2

2

IO密集型,即该任务需要大量的IO,即大量的阻塞。
在单线程上运行IO密集型的任务会导致浪费大量的CPU运算能力浪费在等待。

所以在I0密集型任务中使用多线程可以大大的加速程序运行,即使在单核CPU上,这种加速主要就是利用了被浪费掉的阻塞时间。


IO密集型时,大部分线程都阻塞,故需要多配置线程数:


参考公式:CPU核数 / 1-阻塞系数 阻塞系数在0.8~0.9之间


比如8核CPU:8 / 1 - 0.9= 80个线程数


最后


2022 10/11 20:23


p51~p54


Markdown 已选中 16 字数 1 行数

HTML 2820 字数 109 段落

相关文章
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
71 2
|
1月前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
|
18天前
|
存储 监控 小程序
Java中的线程池优化实践####
本文深入探讨了Java中线程池的工作原理,分析了常见的线程池类型及其适用场景,并通过实际案例展示了如何根据应用需求进行线程池的优化配置。文章首先介绍了线程池的基本概念和核心参数,随后详细阐述了几种常见的线程池实现(如FixedThreadPool、CachedThreadPool、ScheduledThreadPool等)的特点及使用场景。接着,通过一个电商系统订单处理的实际案例,分析了线程池参数设置不当导致的性能问题,并提出了相应的优化策略。最终,总结了线程池优化的最佳实践,旨在帮助开发者更好地利用Java线程池提升应用性能和稳定性。 ####
|
20天前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
53 14
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
14天前
|
监控 Java 开发者
深入理解Java中的线程池实现原理及其性能优化####
本文旨在揭示Java中线程池的核心工作机制,通过剖析其背后的设计思想与实现细节,为读者提供一份详尽的线程池性能优化指南。不同于传统的技术教程,本文将采用一种互动式探索的方式,带领大家从理论到实践,逐步揭开线程池高效管理线程资源的奥秘。无论你是Java并发编程的初学者,还是寻求性能调优技巧的资深开发者,都能在本文中找到有价值的内容。 ####
|
1月前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
112 38
|
1月前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
25天前
|
Java 编译器 程序员
Java面试高频题:用最优解法算出2乘以8!
本文探讨了面试中一个看似简单的数学问题——如何高效计算2×8。从直接使用乘法、位运算优化、编译器优化、加法实现到大整数场景下的处理,全面解析了不同方法的原理和适用场景,帮助读者深入理解计算效率优化的重要性。
30 6