当线程池的有界工作队列排满才需要使用饱和策略,饱和策略要么拒绝新的请求,要么要求请求被延时执行。Java提供了几种拒绝提交任务的方案,可以通过ThreadPoolExecutor类的setRejectedExecutionHandler方法来设置饱和策略。具体参数如下:
<!--[if !supportLists]-->1、
1、CallerRunsPolicy 2、AbortPolicy 3、DiscardPolicy 4、DiscardOldestPolicy
第一种策略为Caller-runs策略,即该线程的执行有调用的这个线程来执行,调用的线程会暂停原来的任务,转而去执行该任务,该任务执行完成后继续执行原来的任务。测试用例如下:
public static void main(String[] args) { BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(1); ThreadPoolExecutor exec = new ThreadPoolExecutor(1, 1, 100, TimeUnit.SECONDS, workQueue); exec.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); System.out.println(new Date()); for(int i=0;i<5;i++) { exec.execute(new Runnable() { @Override public void run() { System.out.println("task run : " + Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } }); } System.out.println(new Date()); exec.shutdown(); }
程序运行结果如图所示:
主线程提交了创建了一个ThreadPoolExecutor,并且容量为1,队列为1,此时最多可以提交两个线程。因为在提交第三个任务的同时,线程池总的线程正在运行,等待队列已满,新的任务无处可放,这里的Caller-runs策略吧这个任务交由调用该请求的线程,也就是main线程来执行这个任务。可以看到,该主线程本身可以在很小的时间内提交任务并结束,但由于他需要执行一定的任务,被延迟了4秒才执行完毕,可以预见main线程在这期间运行了两次任务。
第二种策略为AbortPolicy,该策略保证在线程池满的情况下任何试图提交任务到该线程池的线程的线程均会抛出,RejectedExecutionException,该异常导致调用线程的终止。但这种异常时可以捕获的(非检查型异常)。
第三种策略为DiscardPolicy,该策略保证任何试图向满的线程池提交任务时,该任务的提交会立即返回,任务不会被提交,并且不会抛出任何形式的异常。
最后一种为DiscardOldestPolicy,这种模式下,将会抛弃下一个将要执行的任务,然后把刚提交的任务添加到任务队列,等待执行。
相关推荐
Java线程池工作队列饱和策略代码示例 Java线程池工作队列饱和策略是Java并发编程中的一种重要机制,用于处理线程池中工作队列的饱和问题。在本文中,我们将详细介绍Java线程池工作队列饱和策略的概念、原理和实现。...
4. **线程池饱和策略** - **ArrayBlockingQueue** 和 **LinkedBlockingQueue**:两种常见的工作队列,前者是定长,后者在无界和有界之间。 - **拒绝策略**:当线程池饱和时,可以通过`setRejectedExecutionHandler...
线程池的配置需要根据实际应用的需求进行,包括核心线程数、最大线程数、队列容量以及饱和策略的选择,都需要谨慎考虑,以保证线程池既能高效运行,又能防止资源过度消耗。同时,合理的线程池管理能够帮助开发者调试...
- **RejectedExecutionHandler**:饱和策略,处理线程池饱和时的新任务。 3. **线程池的执行策略** - **AbortPolicy**:默认策略,抛出`RejectedExecutionException`异常。 - **CallerRunsPolicy**:调用者线程...
拒绝策略则是在线程池饱和时,对新提交任务的处理方式,常见的有抛出异常、忽略任务、执行拒绝服务操作等。 在Java中,`java.util.concurrent`包提供了`ExecutorService`接口及其实现类,如`ThreadPoolExecutor`,...
当线程池和任务队列都达到饱和时,新提交的任务将按照拒绝策略处理。 4. `threadNamePrefix`:线程名前缀,用于标识线程池中的线程。 5. `rejectedExecutionHandler`:拒绝策略,当线程池和任务队列都无法接受新任务...
- **饱和策略**:当所有线程都在工作且任务队列也已满时,线程池会根据配置的饱和策略来处理无法接收的任务。 - **线程销毁**:当任务减少时,超过核心线程数的空闲线程会在一定时间内被销毁,而核心线程则会一直...
本文将详细介绍如何使用 Java 中的线程池,包括线程池的概念、线程池的优点、ThreadPoolExecutor 构造函数、饱和策略、线程工厂等。 为什么要使用线程池? 在服务器应用程序中,经常需要处理大量的短小任务。这些...
如果线程池饱和,我们可以通过setRejectedExecutionHandler来修改饱和策略。有四种饱和策略: * 终止Abort(默认):抛出异常由调用者处理。 * 抛弃Discard:抛弃任务。 * 抛弃DiscardOldest:抛弃最旧的任务,注意...
4. **饱和策略(Rejected Execution Handler)**:当线程池和队列都满载时,新提交的任务处理策略,常见的策略有抛弃任务、抛弃最旧任务、抛出异常等。 配置线程池时,我们需要关注以下几点: - **线程池大小**:...
8. `handler`是线程池的饱和策略,当线程池和队列都满时,用来处理被拒绝的任务。 `FutureTask`是一个可以取消的异步计算任务,它实现了`RunnableFuture`接口,提供了获取计算结果和取消任务的功能。它通常与线程池...
- **线程饱和策略**:当任务队列满时,线程池可以采取拒绝策略,如丢弃任务、阻塞提交任务的线程或创建新线程。 3. **C++实现线程池的关键技术**: - **线程库**:C++11及更高版本提供了标准线程库 `<thread>`,...
- handler:饱和策略处理器,当线程池无法处理新提交的任务时,按照既定的策略处理,常见的有AbortPolicy、DiscardPolicy、DiscardOldestPolicy和CallerRunsPolicy。 线程池的执行流程涉及execute()方法,当提交...
线程池会根据其内部策略决定何时以及如何运行这些任务,这样可以避免频繁创建和销毁线程。 2. **时钟线程池(Timer Pool)** 时钟线程池是基于计时器的线程池功能,允许开发者设定一个定时任务,例如使用`System....
4. 如果线程池已满并且阻塞队列也满,就会执行饱和策略(handler,也称为拒绝策略),这可以是抛出异常、忽略任务、调用系统默认处理或自定义处理方式。 Java提供了多种类型的线程池供选择,包括`...
项目描述:对java.util.concurrent包下线程池相关源码进行重新实现,深入研究和学习线程池超时机制、饱和策略、生命周期等知识 ThreadPoolExecutor类下部分方法和内部类介绍: 1、Worker类: 描述:Worker类实现...
5. **任务拒绝策略**:当线程池和任务队列都满载,无法再接收新任务时,线程池会根据预设的拒绝策略处理新任务。例如,可以丢弃新任务,抛出异常,或者让已存在的线程自己处理。 Java的`java.util.concurrent`包...
饱和策略决定了当线程池无法接受新任务时的行为。默认的AbortPolicy会抛出异常,DiscardPolicy会直接丢弃任务,CallerRunsPolicy则由提交任务的线程来执行,DiscardOldestPolicy则会丢弃队列中最旧的任务来执行新的...
- 使用适当的拒绝策略,如AbortPolicy、CallerRunsPolicy、DiscardPolicy或DiscardOldestPolicy,处理线程池饱和情况。 6. **注意事项**: - 确保线程安全:在多线程环境下,共享数据的访问需要同步控制,避免...
- **饱和策略**:当任务队列已满且线程池中的线程数量达到`maxPoolSize`时,Spring提供了多种饱和策略,如丢弃策略、CallerRunsPolicy(由调用者线程执行任务)等。 - **线程生命周期**:Spring允许自定义线程工厂...