线程池参数理解

线程池各参数含义

先来看看源代码,线程池创建都需要传哪些参数,上代码

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

从代码中我们可以看到创建一个线程池是需要7个参数,先给下官方的解释大概了解下:

  1. corePoolSize the number of threads to keep in the pool, even if they are idle,百度翻译:池中要保留的线程数,即使它们处于空闲状态;(也就是我们说的核心线程数)
  2. maximumPoolSize the maximum number of threads to allow in the pool,百度翻译:池中允许的最大线程数;
  3. keepAliveTime when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating,翻译太长:大致意思就是,当 线程数 > corePoolSize时, 多余的这部分线程空闲一定时间后,开始终止线程;
  4. unit the time unit for the {@code keepAliveTime} argument,这个就很简单了,keepAliveTime的单位;
  5. workQueue the queue to use for holding tasks before they are executed. 也没什么好说的,等待队列;
  6. threadFactory the factory to use when the executor creates a new thread. 看的factory大致也能猜到是一个工厂类,用来创建线程;
  7. handler the handler to use when execution is blocked because the thread bounds and queue capacities are reached. 拒绝策略,线程池执行不过来的时候的策略,可自定义,jdk提供了四种拒绝策略。

线程池的工作方式

知道了各参数的含义,可能也不是太明白什么意思,那么我用一件生活中常见的场景来说明下,可以更好的理解各参数以及他们在线程池运行中扮演的角色;

  • 银行办理业务场景
    大家都去过银行吧,而且对于苦逼的上班族来说只有周末才有时间去银行办理业务;周六了,张三带着一个礼拜的加班费来银行办理存款,发现五个窗口只有两个窗口正常办理,其他三个周末不开;来晚了,大厅座椅已经有人在排队,张三拿了号也坐了下来;慢慢人越来越多,等候区已经基本坐满了;值班经理没想到人这么多,就赶紧给同事王五、王六、王七打电话让来加班;几分钟后5个窗口都开通了,可是人还是一直增加,等候区已经爆满,这时候经理安排大厅保安站门口,阻挡要进来的办理业务人员并高诉他们今天已经没号了,不要再进来办理业务;等了一段时间张三终于办理完了业务,已经到了下午,办理业务的人也减少了,5个窗口开始慢慢有空闲的现象,这时候经理对王五六七说如果过10分钟你们窗口还是空闲,你们就可以下班了;场景大致描述完了,不知道大家有没有悟到什么。

  • 银行场景和线程池相似处
    开始的两个窗口其实就是corePoolSize;五个窗口就是maximumPoolSize包含corePoolSize;银行等候区对应的就是workQueue;经理对应的就是threadFactory,他可以安排王五六七来加班,也就是开启新线程;保安站门口阻挡人员就等同于拒绝策略,当然拒绝策略不是真正的拒绝,我们可以自定义,有时候可以加个补偿处理策略;经理说过10分钟没有办理业务的,你们就可以下班,对应的就是线程池的keepAliveTime和unit参数。

创建线程池方式

Excutor

在这里插入图片描述

  • 创建线程池方式
    ExecutorService threadPool = new ThreadPoolExecutor(1,2,1000。。。);
Excutors

在这里插入图片描述

类后面带s的都是辅助工具类,例如String Strings,Array Arrays;

  • 应用Excutors辅助类创建线程池
  1. 创建指定size数 :
    ExecutorService threadPool = Excutors.newFixedThreadPool(5);
    
  2. 创建单线程线程池:
     ExecutorService threadPool = Excutors.newSingleThreadExecutor();
    
  3. 创建一个可缓存线程池:
    ExecutorService threadPool = Excutors.newCachedThreadPool();
    

题外话:为什么大厂不允许用Excutors来创建线程池?其实看Excutors底层代码可以看出,底层还是用了new ThreadPoolExecutor()来创建,但是maxSize默认最大会导致栈溢出,queue默认无界,会导致oom,都是不可取的。

线程池数量选取

一般我们业务分为CPU密集型和IO密集型,两种业务在线程池数量上选取是有差异的。

  • cpu密集型
    线程数 = cpu核数 + 1

  • IO密集型
    线程数 = cpu核数 * 2 + 1
    线程数 = cpu核数 / (1- 0.8~0.9)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
线程池是在多线程编程中常用的一种技术,它可以用来管理和复用线程,从而提高程序的性能和效率。 在Python中,可以使用内置的`concurrent.futures`模块来创建线程池。这个模块提供了`ThreadPoolExecutor`类,它可以用来创建和管理线程池。 下面是一个简单的示例代码,演示了如何使用线程池来执行一批任务: ```python import concurrent.futures # 定义一个任务函数 def task(n): print(f"Executing task {n}") return n * n # 创建一个线程池 with concurrent.futures.ThreadPoolExecutor() as executor: # 提交任务给线程池进行执行 future1 = executor.submit(task, 1) future2 = executor.submit(task, 2) # 获取任务的返回结果 result1 = future1.result() result2 = future2.result() print(f"Result 1: {result1}") print(f"Result 2: {result2}") ``` 在这个例子中,我们首先定义了一个任务函数`task`,它接收一个参数,并返回参数的平方。然后,我们使用`ThreadPoolExecutor`创建了一个线程池,并使用`submit`方法提交了两个任务给线程池。每个任务都会在一个新的线程中执行。 通过`future.result()`方法可以获取每个任务的返回结果。最后,我们打印出了每个任务的结果。 注意,线程池会自动管理线程的创建和销毁,你只需要提交任务给线程池即可。线程池会根据系统资源和线程池的配置自动调整线程数量,以达到最佳的性能和效率。 希望这个示例对你理解Python线程池有所帮助!如果你还有其他问题,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值