线程池
底层实现
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
public ThreadPoolExecutor(int corePoolSize,//核心线程数 int maximumPoolSize,//最大线程数 long keepAliveTime,//无人使用线程,超时会释放 TimeUnit unit,//超时时间 BlockingQueue<Runnable> workQueue,//阻塞队列 ThreadFactory threadFactory,//线程工厂 RejectedExecutionHandler handler//拒绝策略) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
线程池的理解
三种线程池实现方式
ExecutorService threadPool = null;
threadPool = Executors.newFixedThreadPool(5);//固定线程
threadPool = Executors.newCachedThreadPool();//多个线程,可伸缩的池子
threadPool = Executors.newSingleThreadExecutor();//单个线程
四种拒绝策略
ThreadPoolExecutor.AbortPolicy() :大于最大承载(阻塞队列大小+最大线程数),java.util.concurrent.RejectedExecutionException:
ThreadPoolExecutor.CallerRunsPolicy():大于最大承载,谁处理线程池谁解决问题
ThreadPoolExecutor.DiscardPolicy():大于最大承载,直接丢弃任务,不报异常
ThreadPoolExecutor.DiscardOldestPolicy():大于最大承载,尝试去和最早的竞争,也不会抛出异常。
线程池的最大线程数怎么设置
cpu密集型,几核cpu,就是几,可以保持cpu的效率最高。Runtime.getRuntime().availableProcessors()
io密集型:判断你得程序中十分消耗io的资源数,设置max为它的二倍。
测试
/** * ThreadPoolExecutor.AbortPolicy() :大于最大承载(阻塞队列大小+最大线程数),java.util.concurrent.RejectedExecutionException: * ThreadPoolExecutor.CallerRunsPolicy():大于最大承载,谁处理线程池谁解决问题 * ThreadPoolExecutor.DiscardPolicy():大于最大承载,直接丢弃任务,不报异常 * ThreadPoolExecutor.DiscardOldestPolicy():大于最大承载,尝试去和最早的竞争,也不会抛出异常。 */ public class ThreadPoolTest { public static void main(String[] args) { ExecutorService threadPool = new ThreadPoolExecutor(2, 5, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardOldestPolicy()); try { // 1、核心线程池起作用。线程1或线程2工作。 // for (int i = 1; i <= 1; i++) { // /*核心线程池起作用。线程1或线程2工作。 // pool-1-thread-1开始工作*/ // threadPool.execute(()->{ // System.out.println(Thread.currentThread().getName()+"开始工作"); // }); // } //2、阻塞队列发挥作用,线程1、2工作 // for (int i = 1; i <= 5; i++) { // /*阻塞队列发挥作用,线程1、2工作。 // pool-1-thread-1开始工作 // pool-1-thread-2开始工作 // pool-1-thread-1开始工作 // pool-1-thread-2开始工作 // pool-1-thread-1开始工作*/ // threadPool.execute(()->{ // System.out.println(Thread.currentThread().getName()+"开始工作"); // }); // } //3、最大线程池起作用 // for (int i = 1; i <= 8; i++) {//观察i=6,7,8输出结果 // /*阻塞队列发挥作用,线程1、2工作。 // pool-1-thread-2开始工作 // pool-1-thread-4开始工作 // pool-1-thread-5开始工作 // pool-1-thread-3开始工作 // pool-1-thread-1开始工作 // pool-1-thread-5开始工作 // pool-1-thread-4开始工作 // pool-1-thread-2开始工作*/ // threadPool.execute(() -> { // System.out.println(Thread.currentThread().getName() + "开始工作"); // }); // } //4、最大承载:阻塞队列大小+最大线程数。否则执行拒绝策略 for (int i = 1; i <= 9; i++) { threadPool.execute(() -> { System.out.println(Thread.currentThread().getName() + "开始工作"); }); } } catch (Exception e) { e.printStackTrace(); } finally { threadPool.shutdown(); } } }