java多线程(五):线程池详解

本文深入探讨了Java线程池的优势、构造方法及四种类型的线程池:FixedThreadPool、SingleThreadPool、CachedThreadPool和ScheduledThreadPool。通过实例展示了它们的特点和适用场景,并介绍了如何终止线程池中的任务及配置线程池的策略。
摘要由CSDN通过智能技术生成

1、线程池的优势:

  • 重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销。
  • 能有效控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象。
  • 能对线程进行简单的管理。并提供定时执行以及指定间隔循环执行等功能。

ThreadPoolExecutor的构造方法

可以通过ThreadPoolExecutor来创建一个线程池,ThreadPoolExecutor类一共有4个构造方法。其中,拥有最多参数的构造方法:

public ThreadPoolExecutor(int corePoolSize,
							int maximumPoolSize,long keepAliveTime,
							TimeUnit unit,
							BlockingQueue<Runnable> workQueue,
							ThreadFactory threadFactory,
							RejectedExecutionHandler handler)

参数说明:

  • corePoolSize: 线程池核心线程数。默认情况下,核心线程会在线程池中一直存活,即使他们处于闲置状态。如果当前运行的线程数少于corePoolSize,则创建新线程来处理任务;如果当前运行的线程数等于或多于corePoolSize,则不再创建新的线程。
  • maxmumPoolSize: 线程池允许创建的最大线程数。如果任务队列满了并且线程数小于maximumPoolSize时,则线程池仍然会创建新的线程来处理任务。
  • keepAliveTime: 非核心线程闲置的超时时间。超过这个时间,非核心线程会被回收。如果allowCoreThreadTimeout设置为true,核心线程也会被回收。
  • TimeUnit: keepAliveTime参数的时间单位。这是一个枚举,有Days(天)、HOURS(小时)、MINUTES(分钟)、MILLISECONDS(毫秒)、SECONDS(秒)等。
  • workQueue: 任务队列。如果当前线程数大于corePoolSize,则将任务添加到此任务队列中。该任务队列是BlockingQueue类型的,也就是阻塞队列。存储在这里的任务是由ThreadPoolExecutorexecute方法提交来的。
  • threadFactory: 线程工厂。为线程池提供创建新线程的功能,一般情况下无须设置该参数。
  • RejectedExecutionHandler: 饱和策略。这是当前任务队列和线程池都满了时所采取的应对策略,默认是AbordPolicy,表示无法处理新任务,并抛出RejectedExecutionException异常。

RejectedExecutionHandler:饱和策略(共4种):
1.AbordPolicy:无法处理新任务,并抛出RejectedExecutionException异常。
2.CallerRunsPolicy:用调用者所在的线程来处理任务。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。
3.DiscardPolicy:不能执行的任务,并将该任务删除。
4.DiscardOldestPolicy:丢弃队列最近的任务,并执行当前的任务。

线程池的原理,当提交一个新的任务到线程池时,线程池的处理流程如下:
在这里插入图片描述

2、执行

ThreadPoolExecutor有两个方法可以供我们执行,分别是submit()和execute(),我们先来看看这两个方法到底有什么差异。

execute()方法源码:

public void execute(Runnable command) {
   
        if (command == null)
            throw new NullPointerException();
        //获得当前线程的生命周期对应的二进制状态码
        int c = ctl.get();
        //判断当前线程数量是否小于核心线程数量,如果小于就直接创建核心 线程执行任务,创建成功直接跳出,失败则接着往下走.
        if (workerCountOf(c) < corePoolSize) {
   
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //判断线程池是否为RUNNING状态,并且将任务添加至队列中.
        if (isRunning(c) && workQueue.offer(command)) {
   
            int recheck = ctl.get();
            //审核下线程池的状态,如果不是RUNNING状态,直接移除队列中
            if (! isRunning(recheck) && remove(command))
                reject(command);
            //如果当前线程数量为0,则单独创建线程,而不指定任务.
            else if (workerCountOf(recheck) == 0)
                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值