来看看什么是线程池

线程池通过池化思想提高效率,避免频繁创建销毁线程。主要参数包括核心线程数、最大线程数、空闲时间和任务队列等。当任务提交时,线程池会根据这些参数决定是否创建新线程或放入队列。阻塞队列如ArrayBlockingQueue、LinkedBlockingQueue和PriorityBlockingQueue各有特点。拒绝策略包括AbortPolicy、DiscardPolicy、DiscardOldPolicy和CallerRunsPolicy,用于处理任务超额时的情况。

        线程池就是就是池化思想的产物。打个比方,筷子,你吃饭的时候都是去筷子桶去拿,而不是每一次都去买新的筷子。在你第一次吃饭的时候已经买了筷子,所以你后续就不用在去买新的筷子,节省了你去超市的时间和买筷子的钱。

        线程池的参数都有哪些呢?

                1.核心线程数。

                2.最大线程数。

                3.空闲时间。

                4.时间单位。

                5.任务队列。

                6.拒绝策略。

                7.线程工厂。

当我们提交一个任务的时候,线程池会查看核心线程数是不是已经饱和,如果不是的话就执行该任务。如果已经饱和的话就查看任务队列是否已满,如果未满则进入等待队列。如果满的话会查看最大线程数是否饱和,如果饱和的话会执行拒绝策略,如果未饱和,会创建线程执行任务。

1.如果当前工作线程小于核心线程的话,会优先创建一个线程去执行任务,而不是去等待获取一个空闲线程。

2.如果线程池中的任务总数大于核心线程,新加入的任务会加入到任务队列中,直到队列饱和。

3.当一个任务执行完之后,执行器会优先从队列中获取,并且开始执行,直到队列为空。

4.在核心线程饱和并且队列也满的情况下,线程池中的线程小于最大线程数,线程池会创建一个新线程执行任务。

5.在核心线程数饱和,队列已满,线程池中的线程数超出最大线程数就会执行拒绝策略。

阻塞队列

        1.ArrayBlockingQueue: 是一个数组实现的有界队列,队列中的元素按照FIFO排序,ArrayBlockingQueue在创建时必须设置大小。

        2.LinkedBlockingQuere: 是一个列表实现的队列,元素按照FIFO排序,可以设置容量,默认容量为Integer.Max_Value。

        3.PriorityBlockingQueue: 是具有优先级的无界队列。

拒绝策略

        1.AbortPolicy: 拒绝策略,新任务会被拒绝,并且抛出RejectedExecutionException异常,默认的拒绝策略。

        2.DiscardPolicy: 新任务会被抛弃,并且不会抛出异常。

        3.DiscardOldPolicy: 抛弃最老的任务,再次尝试进入队列。

        4.CallerRunsPolicy: 调用者策略,如果新任务添加失败,那么提交任务的线程自己去执行该任务,不会使用线程池中的线程执行该任务。

### 线程池拒绝策略的类型及各自的作用 Java 中 `ThreadPoolExecutor` 提供了几种内置的线程池拒绝策略,这些策略用于当线程池无法继续接收新任务时如何处理提交的任务。以下是常见的几种拒绝策略及其作用: #### 1. **AbortPolicy** 该策略会在任务被拒绝时抛出 `RejectedExecutionException` 异常[^2]。这种策略适用于希望程序能够感知到任务被拒绝的情况,并通过捕获异常来采取进一步措施。 ```java new ThreadPoolExecutor.AbortPolicy(); ``` #### 2. **CallerRunsPolicy** 此策略会由调用者线程(即提交任务的线程)执行被拒绝的任务[^1]。这种方式不会丢弃任务,也不会创建新的线程,而是让当前线程承担额外的工作负载。它通常用于短期过载情况下的恢复机制。 ```java new ThreadPoolExecutor.CallerRunsPolicy(); ``` #### 3. **DiscardPolicy** 该策略会静默地丢弃被拒绝的任务而不做任何处理[^1]。如果可以容忍某些任务偶尔失败,则可以选择此策略以减少资源消耗。 ```java new ThreadPoolExecutor.DiscardPolicy(); ``` #### 4. **DiscardOldestPolicy** 此策略会尝试丢弃最旧的一个未处理请求并重试提交当前任务[^1]。它的目的是为了腾出空间给最新到达的任务,从而避免长时间等待队列中的任务阻塞整个系统。 ```java new ThreadPoolExecutor.DiscardOldestPolicy(); ``` 除了以上四种标准策略外,还可以通过实现 `RejectedExecutionHandler` 接口来自定义拒绝策略[^1]。这允许开发者根据业务逻辑设计更加灵活的行为模式。 --- ### 示例代码展示不同拒绝策略的效果 下面是一个简单的例子展示了如何配置不同的拒绝策略以及它们的表现差异: ```java import java.util.concurrent.*; public class RejectionStrategyExample { public static void main(String[] args) throws InterruptedException { BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2); // 创建带有 CallerRunsPolicy 的线程池实例 ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 2, 0L, TimeUnit.MILLISECONDS, queue, new ThreadPoolExecutor.CallerRunsPolicy() ); for (int i = 0; i < 5; i++) { int taskId = i; executor.submit(() -> System.out.println("Executing Task " + taskId)); } Thread.sleep(100); // 让主线程稍作延迟以便观察结果 executor.shutdownNow(); // 关闭线程池 } } ``` 在这个示例中,由于设置了较小的核心线程数和工作队列容量,超出部分的任务会被交给调用方运行。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值