线程池以及HashTable, HashMap, ConcurrentHashMap之间的区别
什么是线程池线程池Thread Pool是一种线程使用模式提前创建一定数量的线程并进行复用统一管理线程的创建、销毁和调度从而降低线程创建和销毁的开销提高程序响应速度防止线程数量失控导致系统资源耗尽线程池的核心参数Java中线程池的核心实现类是 ThreadPoolExecutor。public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueRunnable workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler )corePoolSize核心线程数线程池中长期存活的线程数量即使空闲也不会被销毁除非设置允许回收作用保证线程池的基本处理能力maximumPoolSize最大线程数线程池中允许存在的最大线程数量当任务很多、队列已满时才会创建新线程作用限制线程数量防止资源耗尽keepAliveTime空闲存活时间非核心线程空闲时最多存活时间超过该时间将被回收unit时间单位keepAliveTime 的时间单位如TimeUnit.SECONDSworkQueue任务队列用于存放等待执行的任务常见实现队列特点LinkedBlockingQueue无界队列可能 OOMArrayBlockingQueue有界队列SynchronousQueue不存任务直接交给线程DelayQueue延时任务threadFactory线程工厂用于创建线程可自定义线程名、优先级、是否守护线程方便排查问题、日志定位handler拒绝策略当线程池线程数已满 队列已满时触发。策略行为AbortPolicy抛异常默认CallerRunsPolicy调用者自己执行DiscardPolicy直接丢弃任务DiscardOldestPolicy丢弃最早任务线程池的工作流程线程池处理任务的完整逻辑可总结为5个步骤:否是否是否是提交任务核心线程池是否满创建核心线程执行任务任务队列是否满任务加入队列等待线程池是否达到最大线程数创建非核心线程执行任务执行拒绝策略Executors创建常见线程池Java提供了Executors工具类快速创建线程池但生产环境不推荐直接使用。FixedThreadPool固定大小线程池ExecutorService pool Executors.newFixedThreadPool(5);特点线程数量固定使用 无界队列 LinkedBlockingQueue风险任务过多可能 OOM(内存溢出)适用场景任务量稳定并发数可控SingleThreadExecutor单线程池ExecutorService pool Executors.newSingleThreadExecutor();特点只有一个线程保证任务顺序执行风险任务堆积可能 OOM(内存溢出)CachedThreadPool缓存线程池ExecutorService pool Executors.newCachedThreadPool();特点线程数不固定空闲线程 60s 回收使用 SynchronousQueue风险线程数无限增长容易耗尽CPUScheduledThreadPool定时线程池ScheduledExecutorService pool Executors.newScheduledThreadPool(3);特点:支持定时、周期任务HashTable, HashMap, ConcurrentHashMap 之间的区别主要区别对比点HashtableHashMapConcurrentHashMap线程安全安全不安全安全实现方式数组链表数组链表红黑树 (JDK 1.8)数组链表红黑树 CAS synchronized锁的粒度synchronized 整表加锁无锁分段锁/桶级锁 (锁定头节点)性能最差最好高并发下最好允许 key 为 null不允许允许 1 个不允许允许 value 为 null不允许允许不允许是否推荐使用不推荐推荐单线程推荐并发扩容机制整体扩容扩容时阻塞所有操作整体扩容扩容时阻塞所有操作分段 / 分桶扩容不阻塞全部操作