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 使用率较高,但是可能遇到不可接受的调度开销,
         * 这样也会降低吞吐量。
         */
        //核心线程满后,会创建线程直到最大线程数,然后会进入队列等待,队列满后执行丢弃策略(在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
}

猜你喜欢

转载自www.cnblogs.com/kelisi-king/p/9149454.html
今日推荐