调试了下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 }