🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 1、线程池 ### 1 为什么要使用线程池 平常使用new Thread(). start( ) 的方式启动的线程,使用完之后就会变成垃圾,被系统销毁掉;如果在任务众多的情况下频繁的开启和销毁线程,就会给系统造成极大的压力;而使用线程池则会对线程进行统一的管理,一个线程在执行完任务后不会被系统回收,而是可以继续执行下一个任务,不会造成线程的频繁启动和销毁,减轻了系统的压力。 ### 2 Java中的线程池 #### 1 ThreadPoolExecutor 基本线程池 ~~~ public ThreadPoolExecutor(int corePoolSize, //该线程池中的核心线程数量 int maximumPoolSize, //该线程中的最大线程数量 long keepAliveTime, //该线程的非核心线程的存活时间(可设置allowCoreThreadTimeOut=true,使超时时间适用于核心线程) TimeUnit unit, //存活时间的单位 有:纳秒,毫秒,微秒,秒,分支,小时,天 BlockingQueue<Runnable> workQueue, //任务队列 ThreadFactory threadFactory, //线程工程,可用于设置线程的名字等属性,一般不使用 RejectedExecutionHandler handler // ) { ... } ~~~ #### 2 线程池的执行策略 当execute( ) 一个任务时: 1. 当**核心线程未满时**,直接启动一个空闲的核心线程去执行任务; 2. 当**核心线程已满而任务队列未满时**,则将任务放在任务队列中,等待某个核心线程执行完任务后执行该任务; 3. 当**核心线程已满并且任务队列也已经满了时**,则启动一个空闲的非核心线程去执行任务; 4. 当**三者(核心线程,任务队列,非核心线程,也可以是最大线程数量和任务队列)均已满**,则会采取饱和策略,拒绝执行该任务,抛出异常 java.util.concurrent.RejectedExecutionException #### 3 Java中内置的线程池 * **FixedThreadPool( )** 线程数量固定,且全部为核心线程,阻塞队列无界 **适用:执行长期的任务,性能较好** ~~~ //源码 public static ExecutorService newFixedThreadPool(int coreSize) { return new ThreadPoolExecutor(coreSize, coreSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); } //创建fixed线程池 final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5); fixedThreadPool.execute(runnable); ~~~ * **CachedThreadPool( )** 没有核心线程,全部为非核心线程,最大线程数量为Integer.MAX\_VALUE,线程存活时间为60s **适用:执行很多短期异步的小程序或者负载较轻的服务器** ~~~ //源码 public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue()); } //创建Cached线程池 final ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); cachedThreadPool.execute(runnable); ~~~ * **ScheduledThreadPool( )** 定时延时执行 **适用:周期性执行任务的场景** ~~~ //源码 public static ScheduledExecutorService newScheduledThreadPool(int coreSize) { return new ScheduledThreadPoolExecutor(coreSize); } //创建Scheduled线程池 final ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3); scheduledThreadPool.schedule(runnable,10,TimeUnit.SECONDS);//延迟启动任务 scheduledThreadPool.scheduleAtFixedRate(runnable,5,1,TimeUnit.SECONDS);//延迟5s后启动,每1s执行一次 scheduledThreadPool.scheduleWithFixedDelay(runnable,5,1,TimeUnit.SECONDS);//启动后第一次延迟5s执行,后面延迟1s执行 ~~~ * **SingleThreadPool( )** 线程池中只要一个核心任务 **适用:一个任务一个任务执行的场景** ~~~ //源码 public static ExecutorService newSingleThreadExecutor() { return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue())); } //创建Single线程池 final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); singleThreadExecutor.execute(runnable); ~~~ * **SingleScheduledThreadPool( )** 只有一个核心线程的延时任务 ~~~ //源码 public static ScheduledExecutorService newSingleThreadScheduledExecutor() { return new Executors.DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1)); } ~~~ | | | | --- | --- | | | | ### 3 Java中的阻塞队列 | **队列名称** | **描述** | | --- | --- | | **ArrayBlockingQueue** | **一个由数组结构组成的有界阻塞队列。** | | **LinkedBlockingQueue** | **一个由链表结构组成的有界阻塞队列。** | | **PriorityBlockingQueue** | **一个支持优先级排序的无界阻塞队列。** | | **DelayQueue** | **一个使用优先级队列实现的无界阻塞队列。** | | **SynchronousQueue** | **一个不存储元素的阻塞队列。** | | **LinkedTransferQueue**| **一个由链表结构组成的无界阻塞队列。** | | **LinkedBlockingDeque** | **一个由链表结构组成的双向阻塞队列。** |