线程池的4种拒绝策略

线程池的4种拒绝策略

1、 中止策略
* 功能:当线程无法加入队列时,就会报异常,然后中止运行。
* 场景: ***
2、 调用者运行策略
* 功能:只要线程池没有关闭,就把任务给到当前线程处理先处理。
* 场景:一般在不允许失败的、对性能要求不高、并发量较小的场景下使用。 因为线程池一般情况下不会关闭,也就是提交的任务一定会被运行,但是由于是调用者线程自己执行的,当多次提交任务时,就会阻塞后续任务执行,性能和效率就会变慢。
3、 丢弃策略
* 功能:直接丢弃任务,不抛出任何错误或者异常
* 场景:如果你的任务无关紧要,那就可以用它。目前这个策略基本用不上了。
4.、弃老策略
* 功能:把最老的任务丢弃,新增新任务。
* 场景:和3一样

代码例子

import java.util.concurrent.*;
public class  ThreadPoolArgumentsMain {
    /**
     * 1. 线程池的七大参数
     * int corePoolSize	核心线程池大小
     * int maximumPoolSize	最核心大线程池大小
     * long keepAliveTime	超时时间 没有人使用会自动释放
     * TimeUnit unit	超时单位
     * BlockingQueue<Runnable> workQueue	阻塞队列
     * ThreadFactory threadFactory	线程工厂,创建线程的,一般不用动
     * RejectedExecutionHandler handler	拒绝策略
     *    1. 抛出异常,中止任务  new ThreadPoolExecutor.AbortPolicy() 线程池默认拒绝策略,当添加到线程池失败就会抛出RejectedExecutionException异常
     *    2. 使用调用线程执行任务 new ThreadPoolExecutor.CallerRunsPolicy() 如果添加失败,那么主线程会自己调用执行器中的execute方法来执行任务
     *    3. 直接丢弃 new ThreadPoolExecutor.DiscardPolicy() 如果添加失败,则放弃,不会抛出异常
     *    4. 丢弃队列最老任务,添加新任务 new ThreadPoolExecutor.DiscardOldestPolicy() 如果添加到线程池失败,会将队列中最古老添加的任务丢弃,再尝试添加,如果失败则按该策略不断重试
     */

    public static void main(String[] args) {
//        AbortPolicy();

//        CallerRunsPolicy();

//        DiscardPolicy();

//        DiscardOldestPolicy();
    }

    /**
     * 中止策略
     * 功能:当线程无法加入队列时,就会报异常,然后中止运行。
     * 场景: ***
     */
    private static void AbortPolicy() {
        int corePoolSize = 2;
        int maximumPoolSize = 5;
        long keepAliveTime = 10;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(8);
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, handler);
        for(int i=0; i< 15; i++) {
            try {
                int n = i + 1;
                executor.execute(() -> {
                    try {  Thread.sleep(2000);  } catch (InterruptedException e) { e.printStackTrace(); }
                    long num = 0;
                    for (long j = 1; j <= 2000000000 ; j++) {
                        num += j;
                    }
                    System.err.println("第" + n + "次使用名称叫" + Thread.currentThread().getName() + "线程,"+"最终入库的数是:"+num);
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        executor.shutdown();
    }

    /**
     * 调用者运行策略
     * 功能:只要线程池没有关闭,就把任务给到当前线程处理先处理。
     * 场景:一般在不允许失败的、对性能要求不高、并发量较小的场景下使用。
     * 因为线程池一般情况下不会关闭,也就是提交的任务一定会被运行,但是由于是调用者线程自己执行的,当多次提交任务时,就会阻塞后续任务执行,性能和效率就会变慢。
     */
    private static void CallerRunsPolicy() {
        int corePoolSize = 2;
        int maximumPoolSize = 5;
        long keepAliveTime = 1;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(8);
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, handler);
        for(int i=0; i< 25; i++) {
            try {
                int n = i + 1;
                executor.execute(() -> {
                    try {  Thread.sleep(2000);  } catch (InterruptedException e) { e.printStackTrace(); }
                    long num = 0;
                    for (long j = 1; j <= 2000000000 ; j++) {
                        num += j;
                    }
                    System.err.println("第" + n + "次使用名称叫" + Thread.currentThread().getName() + "线程,"+"最终入库的数是:"+num);
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        executor.shutdown();
    }


    /**
     * 丢弃策略
     * 功能:直接丢弃任务,不抛出任何错误或者异常
     * 场景:如果你的任务无关紧要,那就可以用它。目前这个策略基本用不上了。
     */
    private static void DiscardPolicy() {
        int corePoolSize = 2;
        int maximumPoolSize = 5;
        long keepAliveTime = 1;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(8);
        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, handler);
        for(int i=0; i< 20; i++) {
            try {
                int n = i + 1;
                executor.execute(() -> {
                    try {  Thread.sleep(2000);  } catch (InterruptedException e) { e.printStackTrace(); }
                    long num = 0;
                    for (long j = 1; j <= 2000000000 ; j++) {
                        num += j;
                    }
                    System.err.println("第" + n + "次使用名称叫" + Thread.currentThread().getName() + "线程,"+"最终入库的数是:"+num);
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        executor.shutdown();
    }

    /**
     * 弃老策略
     * 功能:把最老的任务丢弃,新增新任务。
     *
     */
    private static void DiscardOldestPolicy() {
        int corePoolSize = 2;
        int maximumPoolSize = 5;
        long keepAliveTime = 1;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(8);
        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, handler);
        for(int i=0; i< 25; i++) {
            try {
                int n = i + 1;
                executor.execute(() -> {
                    try {  Thread.sleep(2000);  } catch (InterruptedException e) { e.printStackTrace(); }
                    long num = 0;
                    for (long j = 1; j <= 2000000000 ; j++) {
                        num += j;
                    }
                    System.err.println("第" + n + "次使用名称叫" + Thread.currentThread().getName() + "线程,"+"最终入库的数是:"+num);
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        executor.shutdown();
    }
}

代码都给了!慢慢看吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值