十四、ThreadPoolExecutor线程池的拒绝策略

四种拒绝策略如下
在这里插入图片描述

     * 往线程池中扔4个任务   核心线程数是1 最大线程数是2 队列大小是1
     * 仍第一个任务时 先放入阻塞队列,开启一条线程获取该任务执行
     * 仍第二个任务时 放入阻塞队列
     * 仍第三个任务时 发现核心线程还没有执行完,那新创建线程拿走任务二 并将任务三放入阻塞队列
     * 仍第二个任务时 最大线程已满而且还没有执行完,阻塞队列已满 走拒绝策略

代码如下:

package day10.part2;

import java.util.concurrent.*;

/**
 * 线程池的拒绝策略
 *
 * 1、ThreadPoolExecutor.AbortPolicy:
 *    丢弃任务并抛出RejectedExecutionException异常。
 * 2、ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
 * 3、ThreadPoolExecutor.DiscardOldestPolicy:
 *    丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
 * 4、ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
 *    这里有main线程处理 将main线程也加入线程池  main线程就由线程池控制
 *
 * @author xzq
 */
public class ExecutorTest05 {

    public static void main(String[] args) {
        //  abortPolicy();
        //  discardPolicy();
        //callerRunsPolicy();
      discardOldestPolicy();
        System.out.println("主线程执行完毕!");
    }

    private static void abortPolicy(){
        //创建一个阻塞队列
        BlockingQueue<Runnable> blcQ=new ArrayBlockingQueue<>(1);
        //创建线程工厂
        ThreadFactory threadFactory=new ExecutorTest01.MyThreadFactory();
        //创建拒绝策略
        RejectedExecutionHandler handler=new ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor threadPool=new ThreadPoolExecutor(
                1, 2, 5, TimeUnit.SECONDS, blcQ, threadFactory, handler);
        System.out.println("线程池创建完毕---------------------------------");
        /*
         * 往线程池中扔4个任务   核心线程数是1 最大线程数是2 队列大小是1
         *
         * 仍第一个任务时 先放入阻塞队列,开启一条线程获取该任务执行
         * 仍第二个任务时 放入阻塞队列
         * 仍第三个任务时 发现核心线程还没有执行完,那新创建线程拿走任务二 并将任务三放入阻塞队列
         * 仍第二个任务时 最大线程已满而且还没有执行完,阻塞队列已满 走拒绝策略
         */
        for(int i=0;i<4;i++){
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    sleepSeconds(3);
                }
            });
        }
    }

    private static void discardPolicy(){
        //创建一个阻塞队列
        BlockingQueue<Runnable> blcQ=new ArrayBlockingQueue<>(1);
        //创建线程工厂
        ThreadFactory threadFactory=new ExecutorTest01.MyThreadFactory();
        //创建拒绝策略
        RejectedExecutionHandler handler=new ThreadPoolExecutor.DiscardPolicy();
        ThreadPoolExecutor threadPool=new ThreadPoolExecutor(
                1, 2, 5, TimeUnit.SECONDS, blcQ, threadFactory, handler);
        System.out.println("线程池创建完毕---------------------------------");
        /*
         * 往线程池中扔4个任务   核心线程数是1 最大线程数是2 队列大小是1
         *
         * 仍第一个任务时 先放入阻塞队列,开启一条线程获取该任务执行
         * 仍第二个任务时 放入阻塞队列
         * 仍第三个任务时 发现核心线程还没有执行完,那新创建线程拿走任务二 并将任务三放入阻塞队列
         * 仍第二个任务时 最大线程已满而且还没有执行完,阻塞队列已满 走拒绝策略
         */
        for(int i=0;i<4;i++){
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    sleepSeconds(3);
                }
            });
        }
    }

    private static void callerRunsPolicy(){
        //创建一个阻塞队列
        BlockingQueue<Runnable> blcQ=new ArrayBlockingQueue<>(1);
        //创建线程工厂
        ThreadFactory threadFactory=new ExecutorTest01.MyThreadFactory();
        //创建拒绝策略
        RejectedExecutionHandler handler=new ThreadPoolExecutor.CallerRunsPolicy();
        ThreadPoolExecutor threadPool=new ThreadPoolExecutor(
                1, 2, 5, TimeUnit.SECONDS, blcQ, threadFactory, handler);
        System.out.println("线程池创建完毕---------------------------------");
        //往线程池中扔4个任务
        for(int i=0;i<4;i++){
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    sleepSeconds(3);
                }
            });
        }
    }

    private static void discardOldestPolicy(){
        //创建一个阻塞队列
        BlockingQueue<Runnable> blcQ=new ArrayBlockingQueue<>(1);
        //创建线程工厂
        ThreadFactory threadFactory=new ExecutorTest01.MyThreadFactory();
        //创建拒绝策略
        //RejectedExecutionHandler handler=new ThreadPoolExecutor.DiscardOldestPolicy();

        //自定义拒绝策略
        RejectedExecutionHandler handler= new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                /*
                 * 数据很宝贵,一般是不能扔的  所以要自定义拒绝策略
                 * 把任务放进缓存redis中,生成一些记录或者打印日志 方便后续开发维护
                 */
            }
        };
        /*
         * 从redis中拿出走拒绝策略的Runnable r,然后要继续执行的话,就要往线程池中扔
         */

        ThreadPoolExecutor threadPool=new ThreadPoolExecutor(
                1, 2, 5, TimeUnit.SECONDS, blcQ, threadFactory, handler);
        System.out.println("线程池创建完毕---------------------------------");
        //往线程池中扔4个任务
        for(int i=0;i<4;i++){
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    sleepSeconds(3);
                    System.out.println(Thread.currentThread().getName()+"花了3秒执行结束!");
                }
            });
        }

        //4秒后再扔一个任务给线程池
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadPool.execute(new Runnable() {

            @Override
            public void run() {
                sleepSeconds(5);
                System.out.println(Thread.currentThread().getName()+"花了5秒执行结束!");
            }
        });
    }

    private static void sleepSeconds(int seconds){
        try {
            System.out.println(Thread.currentThread().getName()+"正在执行……");
            Thread.sleep(seconds*1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


}


数据是非常重要的,拒绝策略大都丢弃了任务,为了记录数据我们可以自定义拒绝策略,如下

//创建拒绝策略
        //RejectedExecutionHandler handler=new ThreadPoolExecutor.DiscardOldestPolicy();

        //自定义拒绝策略
        RejectedExecutionHandler myHandler= new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                /*
                 * 数据很宝贵,一般是不能扔的  所以要自定义拒绝策略
                 * 把任务放进缓存redis中,生成一些记录或者打印日志 方便后续开发维护
                 */
            }
        };
        /*
         * 从redis中拿出走拒绝策略的Runnable r,然后要继续执行的话,就要往线程池中扔
         */

        ThreadPoolExecutor threadPool=new ThreadPoolExecutor(
                1, 2, 5, TimeUnit.SECONDS, blcQ, threadFactory, myHandler);
        System.out.println("线程池创建完毕---------------------------------");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值