线程池
1、默认线程池:Executors
public class ExecutorsTest { public static void main(String[] args) { /** * newCachedThreadPool:设定一个可缓存的线程池,当线程池长度超过处理的需要,可以灵活回收空闲线程,如果没有可以回收的才新建线程。 * 没有核心线程数,当线程没有任务60s之后就会回收空闲线程,使用有界队列。同样可以选择是否使用默认线程工厂。 * * CachedThreadPool是一个根据需要创建新线程的线程池 * * corePoolSize => 0,核心线程池的数量为0 * maximumPoolSize => Integer.MAX_VALUE,可以认为最大线程数是无限的 * keepAliveTime => 60L * unit => 秒 * workQueue => SynchronousQueue * 当一个任务提交时,corePoolSize为0不创建核心线程,SynchronousQueue是一个不存储元素的队列,可以理解为队里永远是满的, * 因此最终会创建非核心线程来执行任务。对于非核心线程空闲60s时将被回收。因为Integer.MAX_VALUE非常大,可以认为是可以无限创建线程的,在资源有限的情况下容易引起OOM异常 */ ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); /** * newFixedThreadPool:创建的是定长的线程池,可以控制线程最大并发数,超出的线程会在线程中等待,使用的是无界队列, * 核心线程数和最大线程数一样,当线程池中的线程没有任务时候立刻销毁,使用默认线程工厂。 * * FixedThreadPool是固定核心线程的线程池,固定核心线程数由用户传入 * * corePoolSize => 1,核心线程池的数量为1 * maximumPoolSize => 1,只可以创建一个非核心线程 * keepAliveTime => 0L * unit => 毫秒 * workQueue => LinkedBlockingQueue * 它和SingleThreadExecutor类似,唯一的区别就是核心线程数不同,并且由于使用的是LinkedBlockingQueue,在资源有限的时候容易引起OOM异常 */ ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10); /** * newScheduledThreadPool:支持线程定时操作和周期性操作。 */ ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); /** * newSingleThreadExecutor:创建的是单线程化的线程池,只会用唯一一个工作线程执行任务,可以指定按照是否是先入先出,还是优先级来执行任务。 * 同样使用无界队列,核心线程数和最大线程数都是1个,同样keepAliveTime为0,可选择是否使用默认线程工厂。 * * SingleThreadExecutor是单线程线程池,只有一个核心线程 * * corePoolSize => 1,核心线程池的数量为1 * maximumPoolSize => 1,只可以创建一个非核心线程 * keepAliveTime => 0L * unit => 毫秒 * workQueue => LinkedBlockingQueue * 当一个任务提交时,首先会创建一个核心线程来执行任务,如果超过核心线程的数量,将会放入队列中, * 因为LinkedBlockingQueue是长度为Integer.MAX_VALUE的队列,可以认为是无界队列,因此往队列中可以插入无限多的任务, * 在资源有限的时候容易引起OOM异常,同时因为无界队列,maximumPoolSize和keepAliveTime参数将无效,压根就不会创建非核心线程 */ ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); } }
2、自定义线程池:ThreadPoolExecutor
package com.example.netty.executor;
import java.util.concurrent.*;
/**
* @author luliang
* @date 2021-02-24 15:03
* <p>
* https://blog.csdn.net/vincent_duan/article/details/100880799
*/
public class MyThreadPoolExecutor {
public static void main(String[] args) {
new ThreadPoolExecutor(1,
1,
0,
TimeUnit.SECONDS,
new LinkedBlockingQueue(),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
}
/**
* 通过构造函数,自定义线程池,7大参数
*
* @param corePoolSize 核心线程数,即使它们处于空闲状态,除非设置了{@code allowCoreThreadTimeOut}
* @param maximumPoolSize 池中允许的最大线程数
* @param keepAliveTime 大于核心线程数的线程回收等待时间
* @param unit {@code keepAliveTime}参数的时间单位
* @param workQueue 任务队列
* @param threadFactory 执行器创建新线程时要使用的工厂
* @param handler 线程和队列满后的拒绝策略
* @throws IllegalArgumentException 核心线程数<0、线程回收时间<0、最大线程数<=0、最大线程数<核心线程数,如果有以下情况则抛出异常
* @throws NullPointerException 如果workQueue:任务队列、threadFactory:线程工程、handler:队列满处理策略,任意为空时,抛出空指针异常
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
}
/**
* 时间单位
* TimeUnit为JUC重的时间单位枚举类
*/
public void TimeUnit() {
//微妙
TimeUnit microseconds = TimeUnit.MICROSECONDS;
//纳秒
TimeUnit nanoseconds = TimeUnit.NANOSECONDS;
//毫秒
TimeUnit milliseconds = TimeUnit.MILLISECONDS;
//秒
TimeUnit seconds = TimeUnit.SECONDS;
//分钟
TimeUnit minutes = TimeUnit.MINUTES;
//小时
TimeUnit hours = TimeUnit.HOURS;
//天
TimeUnit days = TimeUnit.DAYS;
}
/**
* 任务队列(阻塞队列)
* BlockingQueue是JUC中阻塞队列的接口,有下面常用的实现类
*
* ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列
* DelayQueue:一个无界延时阻塞队列
* LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列
* LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列
* LinkedTransferQueue:一个由链表结构组成的无界阻塞队列
* PriorityBlockingQueue:一个使用优先级队列实现的无界阻塞队列
* SynchronousQueue:一个不存储元素的阻塞队列
*/
public void BlockingQueue() throws InterruptedException {
BlockingQueue blockingQueue = null;
//添加元素,满抛异常
blockingQueue.add(null);
//添加元素,满返回false,不抛异常
blockingQueue.offer(null);
//添加元素,满返回false,不抛异常,可指定等待时间
blockingQueue.offer(null, 0, null);
//添加元素,满阻塞等待
blockingQueue.put(null);
//移除,空异常
blockingQueue.remove(null);
//移除,空返回null,不抛异常
blockingQueue.poll();
//移除,空返回null,可设置超时时间,不抛异常
blockingQueue.poll(0, null);
//移除,空阻塞等待
blockingQueue.take();
//获取队首元素,空异常
blockingQueue.element();
//获取队首元素,空返回null,不抛异常
blockingQueue.peek();
//获取队列剩余空间
blockingQueue.remainingCapacity();
//是否包含指定元素
blockingQueue.contains(null);
//将队列中的值全部移除,并设置到给定集合中
blockingQueue.drainTo(null);
}
/**
* 线程工厂
* threadFactory:它是ThreadFactory类型的变量,用来创建新线程。默认使用Executors.defaultThreadFactory() 来创建线程。
* Executors.defaultThreadFactory()创建的线程有相同的优先级 NORM_PRIORITY = 5,并且是非守护线程,并且具有相同的组名和相同的前缀
*/
public void ThreadFactory() {
ThreadFactory threadFactory = Executors.defaultThreadFactory();
}
/**
* 拒绝策略
* RejectedExecutionHandler 的4种拒绝策略
* ThreadPoolExecutor提供的4中拒绝策略,为ThreadPoolExecutor的内部类,继承了RejectedExecutionHandler接口
*/
public void RejectedExecutionHandler() {
//ThreadPoolExecutor类有几个内部实现类来处理任务拒绝
//直接抛出异常,这是默认策略
ThreadPoolExecutor.AbortPolicy abortPolicy = new ThreadPoolExecutor.AbortPolicy();
//继续执行任务,用调用者所在的线程来执行任务
ThreadPoolExecutor.CallerRunsPolicy callerRunsPolicy = new ThreadPoolExecutor.CallerRunsPolicy();
//直接丢弃任务
ThreadPoolExecutor.DiscardPolicy discardPolicy = new ThreadPoolExecutor.DiscardPolicy();
//丢弃阻塞队列中靠最前的任务,并执行当前任务
ThreadPoolExecutor.DiscardOldestPolicy discardOldestPolicy = new ThreadPoolExecutor.DiscardOldestPolicy();
}
}