`
zhangwei_david
  • 浏览: 476143 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java 之ThreadPoolExecutor.RejectedExecutionHandler

 
阅读更多

 

  • ThreadPoolExecutor.AbortPolicy()抛出java.util.concurrent.RejectedExecutionException异常 终止策略是默认的饱和策略;
  • ThreadPoolExecutor.CallerRunsPolicy()当抛出RejectedExecutionException异常时,会调rejectedExecution方法 调用者运行策略实现了一种调节机制,该策略既不会抛弃任务也不会爆出异常,而是将任务退回给调用者,从而降低新任务的流量
  • ThreadPoolExecutor.DiscardOldestPolicy()抛弃旧的任务;当新提交的任务无法保存到队列中等待执行时将抛弃最旧的任务,然后尝试提交新任务。如果等待队列是一个优先级队列,抛弃最旧的策略将导致抛弃优先级最高的任务,因此AbortPolicy最好不要和优先级队列一起使用。
  • ThreadPoolExecutor.DiscardPolicy()抛弃当前的任务

 

/**
 *返回给调用者的饱和策略
 * @author zhangwei_david
 * @version $Id: CallerRunsTestClient.java, v 0.1 2014年11月13日 下午3:14:58 zhangwei_david Exp $
 */
public class CallerRunsTestClient {

    /**
     *
     * @param args
     */
    public static void main(String[] args) {
        //等待队列
        final LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(5);
        
        ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 5, 2, TimeUnit.SECONDS, queue);

        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        for (int i = 0; i < 15; i++) {
            executor.execute(new Runnable() {

                public void run() {
                    System.out.println("run-" + Thread.currentThread().getName() + " queue:"
                                       + queue.size());
                    try {
                        TimeUnit.SECONDS.sleep(20);
                    } catch (InterruptedException e) {
                        //logger.error("", e);
                    }
                }
            });
        }
    }

}

 运行的结果是:可以在日志中看有两次是在主线程中运行的

run-pool-1-thread-1 queue:5
run-pool-1-thread-2 queue:5
run-pool-1-thread-3 queue:5
run-main queue:5
run-pool-1-thread-4 queue:5
run-pool-1-thread-5 queue:5
run-pool-1-thread-1 queue:4
run-pool-1-thread-3 queue:2
run-pool-1-thread-2 queue:3
run-main queue:5
run-pool-1-thread-5 queue:4
run-pool-1-thread-4 queue:3
run-pool-1-thread-2 queue:1
run-pool-1-thread-1 queue:1
run-pool-1-thread-3 queue:0

 终止饱和策略是,当提交的任务无法进入等待队列且线程池中创建的线程数量已经达到了最大线程数量的限制,则会拒绝新提交的任务。

/**
 *终止饱和策略
 * @author zhangwei_david
 * @version $Id: AbortTestClient.java, v 0.1 2014年11月13日 下午3:03:47 zhangwei_david Exp $
 */
public class AbortTestClient {

    public static void main(String[] args) {

        final ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 3, 2, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(5));

        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());

        executor.setThreadFactory(new MyThreadFactory("Test"));

        for (int i = 0; i < 10; i++) {
            try {
                executor.execute(new Runnable() {

                    public void run() {
                        //doNothing
                    }
                });
            } catch (RejectedExecutionException e) {
                System.out.println("第" + i + "次提交线程被拒绝!  当前活动线程数:" + executor.getActiveCount()
                    + " 队列长度:" + executor.getQueue().size());
            }
        }
    }
}

 运行的结果:

第8次提交线程被拒绝!  当前活动线程数:3 队列长度:5
第9次提交线程被拒绝!  当前活动线程数:3 队列长度:5
一月 21, 2015 9:11:03 下午 com.cathy.demo.concurrency.executor.threadFactory.MyAppThread run
信息: Created Test-2
一月 21, 2015 9:11:03 下午 com.cathy.demo.concurrency.executor.threadFactory.MyAppThread run
信息: Created Test-1
一月 21, 2015 9:11:03 下午 com.cathy.demo.concurrency.executor.threadFactory.MyAppThread run
信息: Created Test-3
一月 21, 2015 9:11:05 下午 com.cathy.demo.concurrency.executor.threadFactory.MyAppThread run
信息: Exiting Test-3
一月 21, 2015 9:11:05 下午 com.cathy.demo.concurrency.executor.threadFactory.MyAppThread run
信息: Exiting Test-1

DiscardPolicy 是抛弃当前任务

 


/**
 *
 * @author zhangwei_david
 * @version $Id: DiscardTestClient.java, v 0.1 2014年11月13日 下午3:16:28 zhangwei_david Exp $
 */
public class DiscardTestClient {

    /**
     *
     * @param args
     */
    public static void main(String[] args) {
        final ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 3, 2, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(5));

        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());

        for (int i = 0; i < 10; i++) {
            System.out.println(MessageFormat.format("第{0}次提交任务,当前等待队列长度{1}", i, executor.getQueue()
                .size()));
            executor.execute(new Runnable() {

                public void run() {
                    System.out.println(Thread.currentThread().getName());
                    try {
                        TimeUnit.SECONDS.sleep(10);
                    } catch (InterruptedException e) {
                        //logger.error("", e);
                    }
                }
            });

        }
        executor.shutdown();

    }

}
 运行结果是:
第0次提交任务,当前等待队列长度0
第1次提交任务,当前等待队列长度0
pool-1-thread-1
第2次提交任务,当前等待队列长度1
第3次提交任务,当前等待队列长度2
第4次提交任务,当前等待队列长度3
第5次提交任务,当前等待队列长度4
第6次提交任务,当前等待队列长度5
pool-1-thread-2
第7次提交任务,当前等待队列长度5
pool-1-thread-3
第8次提交任务,当前等待队列长度5
第9次提交任务,当前等待队列长度5
pool-1-thread-1
pool-1-thread-2
pool-1-thread-3
pool-1-thread-1
pool-1-thread-3
 通过结果可以发现,提交了10个任务最终只有8个任务被执行!其中有两次被抛弃了!
DiscardOldestPolicy :抛弃最旧的任务

 

 

 

 

/**
 *
 * @author zhangwei_david
 * @version $Id: DiscardOldestTest.java, v 0.1 2015年1月22日 上午9:42:21 zhangwei_david Exp $
 */
public class DiscardOldestTest {

    /**
     *
     * @param args
     */
    public static void main(String[] args) {
        final ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 3, 2, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(5));

        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());

        for (int i = 0; i < 10; i++) {
            System.out.println(MessageFormat.format("第{0}次提交任务,当前等待队列长度{1}", i, executor.getQueue()
                .size()));
            executor.execute(new MyTask(String.valueOf(i)));

        }
        executor.shutdown();

    }

    public static class MyTask implements Runnable {

        private String name;

        /**
         * @see java.lang.Runnable#run()
         */
        public void run() {
            System.out.println(name);
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                //logger.error("", e);
            }
        }

        public MyTask(String name) {
            super();
            this.name = name;
        }

    }

}
 

 

 

 

第0次提交任务,当前等待队列长度0
0
第1次提交任务,当前等待队列长度0
第2次提交任务,当前等待队列长度1
第3次提交任务,当前等待队列长度2
第4次提交任务,当前等待队列长度3
第5次提交任务,当前等待队列长度4
第6次提交任务,当前等待队列长度5
第7次提交任务,当前等待队列长度5
第8次提交任务,当前等待队列长度5
第9次提交任务,当前等待队列长度5
6
7
3
4
5
8
9
 发现第二次和第三次提交的任务被抛弃了!

 

 

 
2
2
分享到:
评论

相关推荐

    JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用

    ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue&lt;Runnable&gt; workQueue, RejectedExecutionHandler handler) 其中,corePoolSize表示线程池维护线程...

    java.util.concurrent.uml.pdf

    例如,ThreadPoolExecutor会使用ThreadFactory来创建线程,它还可能使用RejectedExecutionHandler来处理任务无法加入线程池的情况。ExecutorService提供了提交任务到线程池并返回Future对象的机制,Future对象之后...

    java线程池

    线程池的构造方法`ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue&lt;Runnable&gt; workQueue, RejectedExecutionHandler handler)`中的参数有着至关重要...

    JavaThreaddemo_DEMO_tidecme_线程池Java_源码.zip

    - **handler**: 当线程池和工作队列都满时,新的任务如何处理,可以通过`RejectedExecutionHandler`进行定制。 5. **线程池的生命周期** 线程池有四种状态:RUNNING、SHUTDOWN、STOP和TIDYING。`shutdown()`方法...

    java线程池概念.txt

    RejectedExecutionHandler handler) { if (corePoolSize || maximumPoolSize || maximumPoolSize || keepAliveTime ) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == ...

    Java线程池的拒绝策略实现详解

    Java线程池的拒绝策略实现详解 Java线程池的拒绝策略是指当线程池中的线程数量达到最大值时,如何...当提交的任务数大于核心线程数和最大线程数之和时,ThreadPoolExecutor将抛出RejectedExecutionException异常信息。

    JAVA使用线程池查询大批量数据

    RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); ExecutorService executor = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, ...

    java中ThreadPoolExecutor常识汇总

    Java 中 ThreadPoolExecutor 常识汇总 ThreadPoolExecutor 是 Java 中的一种线程池实现,用于管理线程池中的线程,提高系统的并发处理能力。在 Java 中,线程池技术广泛应用于并发编程中,通过调用 ...

    线程池ThreadPoolExecutor原理源码分析.md

    RejectedExecutionHandler handler) ``` - **`corePoolSize`**: 核心线程数量,线程池在启动时至少保持这么多的工作线程。 - **`maximumPoolSize`**: 最大线程数量,线程池允许的最大线程数量。需要注意的是,虽然...

    线程池ThreadPoolExecutor使用简介与方法实例

    ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler) ``` 其中: * corePoolSize:线程池维护线程的最少...

    线程池原理-ThreadPoolExecutor源码解析

    线程池原理-ThreadPoolExecutor源码解析 1.构造方法及参数 2.阻塞对列: BlockingQueue 3.线程工厂: DefaultThreadFactory 4.拒绝策略: RejectedExecutionHandler 5.执行线程 Executor

    spring线程池ThreadPoolExecutor配置以及FutureTask的使用

    这个类是Spring对Java内置的`java.util.concurrent.ThreadPoolExecutor`的封装,允许开发者在Spring应用上下文中声明式地定义线程池。在本篇文章中,我们将深入探讨`ThreadPoolTaskExecutor`的配置及其使用,并结合`...

    ThreadPoolExecutor运转机制介绍

    在Java并发编程中,`ThreadPoolExecutor` 是一种强大的工具,它可以帮助开发者有效地管理和执行线程。`ThreadPoolExecutor` 提供了一种灵活的方式来配置线程池,通过控制线程的数量、队列的行为以及对超出容量的任务...

    socket 线程池实现

    RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); ExecutorService executor = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, ...

    基于java的线程错误捕获工具 CheckThread.zip

    9. **线程池**: 使用ExecutorService和ThreadPoolExecutor可以管理线程的生命周期,防止过多线程的创建导致资源浪费或系统不稳定。线程池还提供了一种优雅的方式来处理任务异常,例如,可以通过设置`...

    Java线程池完整代码,已经用于实际的项目中,性能稳定.zip

    在Java中,`java.util.concurrent`包提供了`ExecutorService`接口和`ThreadPoolExecutor`类来创建和管理线程池。`ThreadPool.java`很可能是一个自定义的线程池实现,它可能扩展了`ExecutorService`或直接使用`...

    使用线程池ThreadPoolExecutor 抓取论坛帖子列表

    本文将详细讲解如何使用Java中的`ThreadPoolExecutor`来抓取论坛帖子列表,结合源码分析和实用工具的应用。 首先,我们要了解线程池的基本原理。线程池是由一组预先创建的线程组成的,这些线程可以复用,而不是每次...

    java线程池面试知识.docx

    Java线程池是Java多线程编程中一个重要的概念,它是通过Executor框架来实现的,主要目的是为了提高并发性能和管理线程资源。线程池的使用可以避免频繁地创建和销毁线程,降低了系统资源的消耗,同时也能有效地控制...

    java线程池封装j

    - **拒绝策略(RejectedExecutionHandler)**:当线程池和队列都满时,处理新提交任务的策略。 ### 2. Java线程池的工作流程 1. 当有新任务提交时,如果当前线程池的线程数量小于核心线程数,会立即创建新线程执行...

Global site tag (gtag.js) - Google Analytics