• JAVA ThreadPoolExecutor


    调试了下java 的 ThreadPool

    package com.hoowe.sdk.basemodule.util;
    
    import com.google.common.util.concurrent.ThreadFactoryBuilder;
    
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.RejectedExecutionException;
    import java.util.concurrent.RejectedExecutionHandler;
    import java.util.concurrent.SynchronousQueue;
    import java.util.concurrent.ThreadFactory;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    public class ThreadPoolUtil {
        /**
         * 只有核心线程数,并且没有超时机制,因此核心线程即使闲置时,也不会被回收,因此能更快的响应外界的请求.
         */
    //    private ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
    //    private ExecutorService cachedThreadPool = Executors.newCachedThreadPool(Executors.defaultThreadFactory());
    //    private ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
    
        private ExecutorService syncBlockQueueService;
        private ExecutorService arrayBlockQueueService;
        private ExecutorService linkedBlockQueueService;
    
        private void initThreadPool(int corePoolSize, int maxPoolSize, long keepAliveTime, TimeUnit timeUnit) {
            /**
             * RejectedExecutionHandler:饱和策略,也就是当队列和线程数目都满了以后,采取的策略。
             * 有AbortPolicy(直接抛出异常),
             * CallerRunsPolicy(只用调用者所在线程来运行任务),
             * DiscardOldestPolicy(丢弃队列里最近的一个任务,并执行当前任务),
             * DiscardPolicy(不处理,直接丢弃)。当然,还可以自定义策略
             */
    
            /**
             * SynchronousQueue,它将任务直接提交给线程而不保持它们。在此,如果不存在可用于立即运行任务的线程,
             * 则试图把任务加入队列将失败,因此会构造一个新的线程。此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。
             * 直接提交通常要求无界 maximumPoolSizes 以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,
             * 此策略允许无界线程具有增长的可能性。
             */
            //当任务达到最大线程数量时执行丢弃策略
            ThreadFactory syncQueueThreadFactory = new ThreadFactoryBuilder().setNameFormat("Hand-Off-Queue-Thread-%d").build();
            syncBlockQueueService = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, timeUnit, new SynchronousQueue<Runnable>(), syncQueueThreadFactory, new ThreadPoolExecutor.AbortPolicy());
    
            /**
             * 有界队列。当使用有限的 maximumPoolSizes 时,有界队列(如 ArrayBlockingQueue)有助于防止资源耗尽,
             * 但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低 CPU 使用率、
             * 操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,如果它们是 I/O 边界),
             * 则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,CPU 使用率较高,但是可能遇到不可接受的调度开销,
             * 这样也会降低吞吐量。
             */
            //核心线程满后,会进入队列等待,队列满后会创建线程直到最大线程数,线程达到指定的maxPoolSize后执行丢弃策略(在CPU使用率(线程调度)和I/O阻塞直接进行折中选择)
            ThreadFactory arrayQueueThreadFactory = new ThreadFactoryBuilder().setNameFormat("Array-bound-Queue-Thread-%d").build();
            arrayBlockQueueService = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, timeUnit, new ArrayBlockingQueue<Runnable>(3), arrayQueueThreadFactory, new ThreadPoolExecutor.AbortPolicy());
    
            /**
             * 无界队列。使用无界队列(例如,不具有预定义容量的 LinkedBlockingQueue)
             * 将导致在所有 corePoolSize 线程都忙时新任务在队列中等待。这样,创建的线程就不会超过 corePoolSize。
             * (因此,maximumPoolSize 的值也就无效了。)当每个任务完全独立于其他任务,即任务执行互不影响时,适合于使用无界队列;
             * 例如,在 Web 页服务器中。这种排队可用于处理瞬态突发请求,当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。
             */
            //核心线程占用满后,将任务插入等待队列
            ThreadFactory linkQueueThreadFactory = new ThreadFactoryBuilder().setNameFormat("link-unbound-Queue-Thread-%d").build();
            linkedBlockQueueService = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, timeUnit, new LinkedBlockingQueue<Runnable>(), linkQueueThreadFactory, new RejectedExecutionHandler() {
                @Override
                public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                    System.out.println("reject Execution");
                }
            });
        }
    
        private static class Task implements Runnable {
            private String name;
    
            public Task(String name){
                this.name = name;
            }
    
            @Override
            public void run() {
                while (true) {
                    try {
                        System.out.println("线程【" + Thread.currentThread().getName() + "】开始处理 任务:" + name);
                        Thread.sleep(100000000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break;
                    }
                }
            }
        }
    
        private static void printStatus(int taskSubmitted, ThreadPoolExecutor e) {
            StringBuilder s = new StringBuilder()
                    .append("当前线程数量 = ")
                    //当前线程数量
                    .append(e.getPoolSize())
                    .append(", 当前核心线程数量 = ")
                    //当前核心线程数量
                    .append(e.getCorePoolSize())
                    .append(", 当前排队数量 = ")
                    //当前排队数量
                    .append(e.getQueue().size())
                    .append(", 当前排队队列剩余数量 = ")
                    //当前排队队列生育数量
                    .append(e.getQueue().remainingCapacity())
                    .append(", 最大线程数量 = ")
                    //最大线程数量
                    .append(e.getMaximumPoolSize())
                    .append(", 已经提交的任务数量 = ")
                    //已经提交的任务数量
                    .append(taskSubmitted)
                    .append("当前队列首个任务:");
    
            System.out.println(s.toString());
        }
    
        public static void main(String[] args) {
            ThreadPoolUtil threadPoolUtil = new ThreadPoolUtil();
            int corePoolSize = Runtime.getRuntime().availableProcessors();
            int maxPoolSize = 5;
            long keepAliveTime = 10;
            TimeUnit timeUnit = TimeUnit.SECONDS;
            threadPoolUtil.initThreadPool(corePoolSize, maxPoolSize, keepAliveTime, timeUnit);
    
    
            for (int i = 0; i < 10; i++) {
                try {
                    threadPoolUtil.syncBlockQueueService.execute(new Task("SyncQueue Task = "+i));
                } catch (RejectedExecutionException e) {
                    System.out.println("#### Sync Queue #### Task rejected = " + (i + 1) + " E:线程数量达到最大");
                }
                printStatus(i + 1, (ThreadPoolExecutor) threadPoolUtil.syncBlockQueueService);
            }
    
    
            System.out.println();
            System.out.println();
    
            for (int i = 0; i < 10; i++) {
                try {
                    threadPoolUtil.arrayBlockQueueService.execute(new Task("ArrayQueue Task = "+i));
                } catch (RejectedExecutionException e) {
                    System.out.println("#### Array Queue #### Task rejected = " + (i + 1) + " E:");
                }
                printStatus(i + 1, (ThreadPoolExecutor) threadPoolUtil.arrayBlockQueueService);
            }
    
            System.out.println();
            System.out.println();
    
            for (int i = 0; i < 10; i++) {
                try {
                    threadPoolUtil.linkedBlockQueueService.execute(new Task("linkedQueue Task = "+i));
                } catch (RejectedExecutionException e) {
                    System.out.println("#### linked Queue #### Task rejected = " + (i + 1) + " E:");
                }
                printStatus(i + 1, (ThreadPoolExecutor) threadPoolUtil.linkedBlockQueueService);
            }
    
        }
    
    
    //    class ThreadFactory extends java.util.concurrent.ThreadFactory
    }
  • 相关阅读:
    [Android]Android系统启动流程源码分析
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q63-Q65)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q60-Q62)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q57-Q59)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q54-Q56)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q51-Q53)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q48-Q50)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q45-Q47)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q40-Q44)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q35-Q39)
  • 原文地址:https://www.cnblogs.com/kelisi-king/p/9149454.html
Copyright © 2020-2023  润新知