第二季: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 段落

相关文章
|
4月前
|
SQL druid Java
线程池相关故障问题之Druid数据库连接池中,为何需要设置TransactionTimeout
线程池相关故障问题之Druid数据库连接池中,为何需要设置TransactionTimeout
126 0
|
2月前
|
Java Spring
spring多线程实现+合理设置最大线程数和核心线程数
本文介绍了手动设置线程池时的最大线程数和核心线程数配置方法,建议根据CPU核数及程序类型(CPU密集型或IO密集型)来合理设定。对于IO密集型,核心线程数设为CPU核数的两倍;CPU密集型则设为CPU核数加一。此外,还讨论了`maxPoolSize`、`keepAliveTime`、`allowCoreThreadTimeout`和`queueCapacity`等参数的设置策略,以确保线程池高效稳定运行。
221 10
spring多线程实现+合理设置最大线程数和核心线程数
|
1月前
|
Java
线程池设置原则
线程池设置原则
|
1月前
|
设计模式 Java 物联网
【多线程-从零开始-玖】内核态,用户态,线程池的参数、使用方法详解
【多线程-从零开始-玖】内核态,用户态,线程池的参数、使用方法详解
55 0
|
3月前
|
缓存 Java
异步&线程池 线程池的七大参数 初始化线程的4种方式 【上篇】
这篇文章详细介绍了Java中线程的四种初始化方式,包括继承Thread类、实现Runnable接口、实现Callable接口与FutureTask结合使用,以及使用线程池。同时,还深入探讨了线程池的七大参数及其作用,解释了线程池的运行流程,并列举了四种常见的线程池类型。最后,阐述了在开发中使用线程池的原因,如降低资源消耗、提高响应速度和增强线程的可管理性。
异步&线程池 线程池的七大参数 初始化线程的4种方式 【上篇】
|
3月前
|
消息中间件 Java 大数据
"深入理解Kafka单线程Consumer:核心参数配置、Java实现与实战指南"
【8月更文挑战第10天】在大数据领域,Apache Kafka以高吞吐和可扩展性成为主流数据流处理平台。Kafka的单线程Consumer因其实现简单且易于管理而在多种场景中受到欢迎。本文解析单线程Consumer的工作机制,强调其在错误处理和状态管理方面的优势,并通过详细参数说明及示例代码展示如何有效地使用KafkaConsumer类。了解这些内容将帮助开发者优化实时数据处理系统的性能与可靠性。
86 7
|
4月前
|
SQL Java Unix
Android经典面试题之Java中获取时间戳的方式有哪些?有什么区别?
在Java中获取时间戳有多种方式,包括`System.currentTimeMillis()`(毫秒级,适用于日志和计时)、`System.nanoTime()`(纳秒级,高精度计时)、`Instant.now().toEpochMilli()`(毫秒级,ISO-8601标准)和`Instant.now().getEpochSecond()`(秒级)。`Timestamp.valueOf(LocalDateTime.now()).getTime()`适用于数据库操作。选择方法取决于精度、用途和时间起点的需求。
61 3
|
4月前
|
NoSQL Java 应用服务中间件
Java高级面试题
Java高级面试题
107 1
|
4月前
|
网络协议 安全 前端开发
java面试题
java面试题
|
4月前
|
监控 Java
多线程线程池问题之创建线程如何解决
多线程线程池问题之创建线程如何解决

热门文章

最新文章

下一篇
无影云桌面