1、是什么?
线程池是一个线程管理技术,创建一个或者多个线程进行管理,避免线程的创建和销毁带来的开销
2、优势
1、降低资源消耗,不必反复创建线程与销毁线程节省资源消耗
2、提高响应速度,不必等待线程的创建,正常情况下(没有任务进入队列的情况)不需要等待。
3、线程管理,线程统一由线程池管理,随取随用。
3、如何使用
1、通过Executors工具类创建
ExecutorService executorService2 = Executors.newSingleThreadExecutor(); //一池一线程,只有一个工作线程 for (int i = 0; i < 10; i++) { executorService2.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }); } executorService2.shutdown();
ExecutorService executorService = Executors.newFixedThreadPool(3); //一池固定线程数 for (int i = 0; i < 10; i++) { executorService.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }); } executorService.shutdown();
ExecutorService executorService1 = Executors.newCachedThreadPool(); //一池不固定线程数,无核心线程,非核心线程数量无限 for (int i = 0; i < 10; i++) { executorService1.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }); } executorService1.shutdown();
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3); //核心数有限,非核心无限 for (int i = 0; i < 10; i++) { scheduledExecutorService.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }); } scheduledExecutorService.shutdown();
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3); //核心数有限,非核心无限 for (int i = 0; i < 10; i++) { scheduledExecutorService.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }); } scheduledExecutorService.shutdown();
底层都是调用的ThreadPoolExecutor构造方法
2、自定义线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,5,
1, TimeUnit.SECONDS,new LinkedBlockingQueue(5));
for (int i = 0; i < 10; i++) {
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + threadPoolExecutor.getTaskCount());
System.out.println();
}
});
}
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
threadPoolExecutor.shutdown();
ThreadPoolExecutor,创建线程池的构造函数,他可以接受7个参数
int corePoolSize, 核心线程数,线程池中主要的工作线程数量 int maximumPoolSize, 最大线程数,当核心工作线程和队列满了,创建新的线程,池中最多能容纳的线程数 long keepAliveTime, 非核心线程的存活时间,到时销毁 TimeUnit unit, 时间单位 BlockingQueue<Runnable> workQueue, 阻塞队列,核心工作数满了,进入队列等待 ThreadFactory threadFactory, 线程工厂,用于创建线程 RejectedExecutionHandler handler 拒绝策略,最大线程满了,队列也满,此时如何拒绝添加进来的任务 4种拒绝策略: 1、AbortPolicy,丢弃并抛出异常(默认) 2、CallerRunsPolicy 由调用线程处理 3、DiscardPolicy 丢弃任务不抛出异常 4、DiscardOldestPolicy 丢弃最早任务,重新尝试
由调用线程执行的情况
丢弃最早任务的情况(任务丢失)
使用execute执行任务
/* *分三步进行: * 1.如果运行的线程少于corePoolSize,尝试以给定的命令作为第一个命令启动新线程 * 2.如果任务可以成功排队,那么我们仍然需要重新检查是否应该添加线程,否则加入队列 * 3.如果我们无法对任务进行排队,则尝试添加新的线程。如果它失败了,我们知道我们已经关闭或饱和了因此拒绝该任务。 */