1 池化思想
程序的运行的本质是占用系统的资源,而池化技术就是优化资源的使用,比如线程池、连接池、内存池、对象池等等,因为频繁的创建和回收资源也是一种浪费资源的过程,所以使用池化技术,将各种资源事先创建好,等到有进程或线程请求的时候再进行分配,使用完成后进行回收,这样就会很大程度的较少浪费。
一句话总结:池化技术就是事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我。
网络异常,图片无法展示
|
线程池的好处:
1、降低资源的消耗
2、提高响应的速度
3、方便管理。
2 线程池的使用和源码分析
《阿里巴巴Java开发手册》中说明:
网络异常,图片无法展示
|
2.1 三大方法
//创建单个线程 ExecutorService threadPool1 = Executors.newSingleThreadExecutor(); //创建一个固定的线程池的大小 ExecutorService threadPool2 = Executors.newFixedThreadPool(5); //可伸缩的,遇强则强,遇弱则弱 ExecutorService threadPool3 = Executors.newCachedThreadPool(); 复制代码
2.2 七大参数
源码:
/** * @param corePoolSize: 保留在池中的线程数,即使它们是空闲的,除非{@code allowCoreThreadTimeOut}被设置 * @param maximumPoolSize: 池中允许的最大线程数 * @param keepAliveTime: 当线程数大于核心时,这是多余的空闲线程在终止之前等待新任务的最大时间。 * @param unit: {@code keepAliveTime}参数的时间单位 * @param workQueue: 在执行任务之前用于保存任务的队列。这个队列将只保存由{@code execute}方法提交的{@code Runnable}任务。 * @param threadFactory: 执行程序创建新线程时使用的工厂 * @param handler: 由于达到线程边界和队列容量而阻塞执行时使用的处理程序 * @throws IllegalArgumentException if one of the following holds:<br> * {@code corePoolSize < 0}<br> * {@code keepAliveTime < 0}<br> * {@code maximumPoolSize <= 0}<br> * {@code maximumPoolSize < corePoolSize} * @throws NullPointerException if {@code workQueue} * or {@code threadFactory} or {@code handler} is null */ 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.acc = System.getSecurityManager() == null ? null : AccessController.getContext(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; } 复制代码
使用:
public static void testThreadPool1() { ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 5, 3, TimeUnit.SECONDS, new LinkedBlockingDeque<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardOldestPolicy()); for (int i = 0; i < 10; i++) { executor.execute(() -> { System.out.println(Thread.currentThread().getName()); }); } } public static void main(String[] args) { testThreadPool1(); } 复制代码
网络异常,图片无法展示
|
2.3 四种拒绝策略
网络异常,图片无法展示
|
/** * A handler for rejected tasks that runs the rejected task * directly in the calling thread of the {@code execute} method, * unless the executor has been shut down, in which case the task * is discarded. */ /* 被拒绝的任务的处理程序,它直接在{@code execute}方法的调用线程中运行被拒绝的任务,除非执行程序已经关闭,在这种情况下任务将被丢弃。 */ public static class CallerRunsPolicy implements RejectedExecutionHandler { ...... } /** * A handler for rejected tasks that throws a * {@code RejectedExecutionException}. */ /* 被拒绝任务的处理程序,该任务抛出 {@code RejectedExecutionException}。 */ public static class AbortPolicy implements RejectedExecutionHandler { ...... } /** * A handler for rejected tasks that silently discards the * rejected task. */ /* 被拒绝任务的处理程序,该处理程序静默地丢弃被拒绝的任务。 */ public static class DiscardPolicy implements RejectedExecutionHandler { ...... } /** * A handler for rejected tasks that discards the oldest unhandled * request and then retries {@code execute}, unless the executor * is shut down, in which case the task is discarded. */ /* 被拒绝任务的处理程序,丢弃最老的未处理任务请求,然后重试{@code execute},除非执行器关闭,在这种情况下任务将被丢弃。 */ public static class DiscardOldestPolicy implements RejectedExecutionHandler { ...... } 复制代码
3 总结和扩展
池的最大的大小如何去设置?
- CUP密集型 N+1(N为CPU核数)
- IO密集型 2N(N为CPU核数)
public static void main(String[] args) { // 最大线程到底该如何定义 // 1、CPU 密集型,几核,就是几,可以保持CPU的效率最高! // 2、IO 密集型 > 判断你程序中十分耗IO的线程, // 程序 15个大型任务 io十分占用资源! // 获取CPU的核数 System.out.println(Runtime.getRuntime().availableProcessors()); }