线程池的使用

假定某业务需要需要线程池来置顶任务。

设置线程池基本参数如下,观察执行情况:

核心线程数:2;最大线程数5;队列长度为3.

class TaskProcess {
    public void run() {
        // 最大线程到底该如何定义
        // 1、CPU 密集型,几核,就是几,可以保持CPu的效率最高!
        // 2、IO  密集型   > 判断你程序中十分耗IO的线程,
        //   假设 程序有15个大型任务 ,io十分占用资源,那就至少留15个max线程(一般来两倍)
        // 获取CPU的核数
        //System.out.println(Runtime.getRuntime().availableProcessors());

        //手动创建线程成
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                //抛出RejectedExecutionException的被拒绝任务的处理程序。
                new ThreadPoolExecutor.AbortPolicy()

                //被拒绝任务的处理程序,直接在execute方法的调用线程中运行被拒绝的任务(main线程执行),除非执行程序已关闭,在这种情况下,任务将被丢弃。
                //new ThreadPoolExecutor.CallerRunsPolicy()

                //拒绝任务的处理程序,丢弃最旧的未处理请求,然后重试execute ,除非执行程序被关闭,在这种情况下任务被丢弃。
                //new ThreadPoolExecutor.DiscardOldestPolicy()

                //被拒绝任务的处理程序,它默默地丢弃被拒绝的任务。
                //new ThreadPoolExecutor.DiscardOldestPolicy()
        );

        try {
            for (int i = 0; i < 10; i++) {

                int finalI = i;
                poolExecutor.execute(() -> {
                    try {
                        //业务代码
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    printInfo(poolExecutor, finalI + "");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            poolExecutor.shutdown();
        }
    }

    public static void printInfo(ThreadPoolExecutor executor, String name) {
        BlockingQueue<Runnable> queue = executor.getQueue();
        System.out.println(Thread.currentThread().getName() + "--->" + name + "<----" +
                " 核心数: " + executor.getCorePoolSize() +
                " 活动线程数: " + executor.getActiveCount() +
                " 最大线程数: " + executor.getMaximumPoolSize() +
                " 任务完成数: " + executor.getCompletedTaskCount() +
                " 队列大小: " + (queue.size() + queue.remainingCapacity()) +
                " 当前排队线程数: " + queue.size() +
                " 队列剩余大小: " + queue.remainingCapacity()
        );
    }

}

观察不同拒绝策略的执行效果:

new ThreadPoolExecutor.AbortPolicy():抛出RejectedExecutionException的被拒绝任务的处理程序。{当达到线程池的最大处理能力的时候,直接抛异常,一些比较重要的业务可以采用该策略,当线程池达到最大负载的时候通过异常信息及时发现}

预期:线程池可以处理8个并发任务,提交10个任务会报异常。

 

 

 

 

 

 

 

 

 

 

posted @ 2022-09-09 11:22  iyandongsheng  阅读(82)  评论(0编辑  收藏  举报