线程池的四种拒绝策略实践

1 ThreadPoolExecutor.AbortPolicy

抛出 RejectedExecutionException来拒绝新任务的处理

//第一种拒绝策略
    //最大核心线程 1
    //最大线程 2
    //队列长度 1
    private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1,2,10, TimeUnit.SECONDS,new ArrayBlockingQueue<>(1));

    public static void main(String[] args) throws InterruptedException {
        //一共放置四个线程

        //第一个线程交给核心线程执行
        threadPool.execute(()->{
            System.out.println("第一任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程到达最大值,第二个线程放进任务队列
        threadPool.execute(()->{
            System.out.println("第二任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程已满,任务队列已满,第三个线程交给新开的普通线程
        threadPool.execute(()->{
            System.out.println("第三任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程已满,任务队列已满,总线程数已满,执行拒绝策略,不去执行第四个任务,并抛出RejectedExecutionException异常
        threadPool.execute(()->{
            System.out.println("第四任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });


        Thread.sleep(100000);

        System.out.println("全部任务执行");
    }
Connected to the target VM, address: '127.0.0.1:57394', transport: 'socket'
第一任务开始执行
第三任务开始执行
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task test.ThreadTest.ThreadPool.RejectedExecution$$Lambda$4/716143810@1888ff2c rejected from java.util.concurrent.ThreadPoolExecutor@6adca536[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]
	at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
	at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
	at test.ThreadTest.ThreadPool.RejectedExecution.main(RejectedExecution.java:55)
第二任务开始执行

2 ThreadPoolExecutor.CallerRunsPolicy

多出来任务的先让main线程帮忙处理,main线程在处理期间提交的任务会阻塞在任务队列外

//第二种拒绝策略,可以扩展
    //最大核心线程 1
    //最大线程 2
    //队列长度 1
    private static ThreadPoolExecutor threadPool1 = new ThreadPoolExecutor(1,2,10, TimeUnit.SECONDS,new ArrayBlockingQueue<>(1),new ThreadPoolExecutor.CallerRunsPolicy());


    public static void main(String[] args) throws InterruptedException {
        //一共放置四个线程

        //第一个线程交给核心线程执行
        threadPool1.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第一任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程到达最大值,第二个线程放进任务队列
        threadPool1.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第二任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程已满,任务队列已满,第三个线程交给新开的普通线程
        threadPool1.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第三任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程已满,任务队列已满,总线程数已满,执行拒绝策略,使用主线程main执行
        threadPool1.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第四任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        //我们不知道 第五条干啥去了 初步推测在队列外等着,直到第二任务被拿出,第五任务放入队列
        threadPool1.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第五任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });



        Thread.sleep(100000);

        System.out.println("全部任务执行");
    }
Connected to the target VM, address: '127.0.0.1:57525', transport: 'socket'
pool-2-thread-1第一任务开始执行
pool-2-thread-2第三任务开始执行
main第四任务开始执行
pool-2-thread-1第二任务开始执行
pool-2-thread-2第五任务开始执行

3 ThreadPoolExecutor.DiscardPolicy

直接丢弃

  //第三种拒绝策略,直接抛弃掉
    //最大核心线程 1
    //最大线程 2
    //队列长度 1
    private static ThreadPoolExecutor threadPool2 = new ThreadPoolExecutor(1,2,10, TimeUnit.SECONDS,new ArrayBlockingQueue<>(1),new ThreadPoolExecutor.DiscardPolicy());


    public static void main(String[] args) throws InterruptedException {
        //一共放置四个线程

        //第一个线程交给核心线程执行
        threadPool2.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第一任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程到达最大值,第二个线程放进任务队列
        threadPool2.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第二任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程已满,任务队列已满,第三个线程交给新开的普通线程
        threadPool2.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第三任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程已满,任务队列已满,总线程数已满,执行拒绝策略,直接抛弃
        threadPool2.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第四任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        Thread.sleep(100000);

        System.out.println("全部任务执行完成!");
    }
Connected to the target VM, address: '127.0.0.1:57607', transport: 'socket'
pool-3-thread-1第一任务开始执行
pool-3-thread-2第三任务开始执行
pool-3-thread-1第二任务开始执行

4 ThreadPoolExecutor.DiscardOldestPolicy

把最早未处理的任务丢弃

  //第四种拒绝策略,抛弃掉队列中最早未处理的任务需求
    //最大核心线程 1
    //最大线程 2
    //队列长度 1
    private static ThreadPoolExecutor threadPool3 = new ThreadPoolExecutor(1,2,10, TimeUnit.SECONDS,new ArrayBlockingQueue<>(1),new ThreadPoolExecutor.DiscardOldestPolicy());


    public static void main(String[] args) throws InterruptedException {
        //一共放置四个线程

        //第一个线程交给核心线程执行
        threadPool3.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第一任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程到达最大值,第二个线程放进任务队列
        threadPool3.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第二任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程已满,任务队列已满,第三个线程交给新开的普通线程
        threadPool3.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第三任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        //因为核心线程已满,任务队列已满,总线程数已满,执行拒绝策略,抛弃已经在队列中的第二任务,将第四任务加入任务队列
        threadPool3.execute(()->{
            System.out.println(Thread.currentThread().getName()+"第四任务开始执行");
            try {
                //睡10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        Thread.sleep(100000);

        System.out.println("全部任务执行完成!");
    }
Connected to the target VM, address: '127.0.0.1:57682', transport: 'socket'
pool-4-thread-1第一任务开始执行
pool-4-thread-2第三任务开始执行
pool-4-thread-2第四任务开始执行
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值