线程池(Java)

线程池

线程池,其实就是一个线程的缓冲池。它可以有效的降低创建、销毁线程的开销。维护一些线程在线程池内,方便使用。

线程池的核心参数:

  1. int corePoolSize 线程池核心线程数量
  2. int maximumPoolSize 线程池最大线程数量
  3. long keepAliveTime 临时线程运行完毕后的存活时间
  4. TimeUnit unit 存活时间单位
  5. BlockingQueue<Runnable> workQueue 任务等待队列
  6. ThreadFactory threadFactory 线程工厂
  7. RejectedExecutionHandler handler 拒绝策略

我们举一个栗子:

假如一家工厂有一条生产线,从人才市场聘请了5个正式工人来生产商品,刚开始工人够用,每天生产商品,但过了3个月后,订单越来越多,工人已经忙不过来了,排队的订单已经堆积在仓库了,这个时候厂长又赶紧到人才市场临时聘请了5个工人,一起生产,但又过了3个月,排队的订单越来越多,厂长就拒绝了后续进来的订单,又从人才市场聘请了5个临时工人,效率提高了之后,仓库里的订单也慢慢消化掉了,过了1个月所有订单都生产完毕了,厂长留了这10个临时工1个月,以防止订单过剩的情况,1个月过后,这10个人也离职了,工厂继续靠5个正式工人进行生产。

在这个例子当中,正式工人就相当于corePoolSize

正式工人 + 临时工人相当于maximumPoolSize

留下临时工人一个月,防止订单过量就像当于keepAliveTime

仓库就相当于workQueue

人才市场就相当于threadFactory

拒绝后续订单就相当于RejectedExecutionHandler

 

也就是说你定义了一个线程池,那么corePoolSize就相当于你的线程池有多少条正式线程,来接收外部提供进来的任务,当所有正式线程都在工作时,如果外部还提交任务到线程池,那么就会进入等待队列,直到队列也满了之后,就会开启临时线程去处理队列中的任务,临时线程的最大数就是maximumPoolSize - corePoolSize的数量,等到线程池内线程数量满了之后,如果外部还有任务提交进来,就是使用RejectedExecutionHandler来拒绝提交进来的任务,等临时线程工作完毕后,线程池会维护到它的存活时间完毕后再销毁临时线程。而在这个例子当中,所有的线程都是通过threadFactory来创建的。

以上就是线程池所有参数的详解。


 

 不同类型的RejectedExecutionHandler:

     AbortPolicy: 当核心数、最大数、队列都已经满了的时候,采用此策略,会直接抛出RejectedException。

     DiscardPolicy:当核心数、最大数、队列都已经满了的时候,采用此策略,会放弃掉刚刚提交的任务。

     DiscardOldestPolicy:当核心数、最大数、队列都已经满了的时候,采用此策略,会放弃掉队列最前面的任务。

     CallerRunsPolicy:当核心数、最大数、队列都已经满了的时候,采用此策略,会在提交此任务的线程上执行任务。

 

     

我们来看一下Java已经为我们准备好的线程池类

1. CachedThreadPool

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

CacheThreadPool(缓存线程池):

该线程池内所有的线程都为临时线程,最大维护线程数为Integer.MAX_VALUE,存活时间为1分钟,提交进来一个任务,就开启一个线程去执行,执行完毕后维护1分钟。

2. FixedThreadPool

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

FixedThreadPool(固定线程池):

该线程池内核心数和最大数一致,提交任务就开启线程执行,线程完毕后不缓存。

3. SingleThreadExecutor

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

该线程池只缓存一个线程去执行。

4. ScheduledThreadPool(周期性执行线程池):

    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

该线程池周期性执行任务,类似于Timmer

### Java 线程池的概念 线程池Java并发编程中的关键概念,用于高效管理大量并发任务。其核心在于减少频繁创建和销毁线程带来的资源消耗,从而提升系统的响应性和吞吐量[^1]。 ### 基本组件与接口 Java 中的线程池实现主要依赖于 `java.util.concurrent` 包下的 `Executor` 接口及其子接口 `ExecutorService`,还有具体的实现类如 `ThreadPoolExecutor`。开发者能够利用这些工具来构建并控制线程池的行为,同时调整各种参数以适应特定的应用场景需求[^2]。 ### 创建固定大小的线程池 (Fixed Thread Pool) 一种常用的线程池形式是由 `Executors.newFixedThreadPool(int nThreads)` 方法提供的固定数量的工作线程组成的集合。这种类型的线程池适合处理具有相似优先级的任务集,在所有工作完成后会保持活动状态直到被显式关闭。 ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FixedThreadPoolExample { public static void main(String[] args) { // 创建一个拥有两个线程的固定大小线程池 ExecutorService executor = Executors.newFixedThreadPool(2); Runnable task = () -> System.out.println(Thread.currentThread().getName() + ": Executing Task"); // 提交多个任务给线程池执行 for (int i = 0; i < 5; ++i) { executor.submit(task); } // 关闭线程池 executor.shutdown(); } } ``` ### 参数配置的重要性 为了达到最优性能表现,合理设定线程池的各项参数至关重要。这不仅有助于提高程序运行效率,还能改善代码的整体质量和可维护性。例如,适当增加最大允许线程数可以在高负载情况下加快任务处理速度;而设置合理的队列长度则能有效防止内存溢出等问题的发生[^3]。 ### 性能优势 采用预初始化的方式使得当新任务到来时不必经历完整的线程启动过程即可立即投入使用,因此大大提高了系统对于请求的反应速率[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值