java线程池
ThreadPoolExecutor定义
首先,在这个类里提供了四个构造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
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.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
其核心是第四个构造方法,其余三个可以发现最终都在调用第四个构造方法,那么我们在运用线程池的时候,一般是直接调用第四个构造方法,那么我们来分析一下这个构造方法里的七个参数:
- corePoolSize:核心线程数
- maximumPoolSize:最大线程数
- keepAliveTime:表示线程没有任务执行时的存活时间
- unit:keepAliveTime的单位
- workQueue:一个阻塞队列
- threadFactory:线程工厂,主要用来生产线程
- handler:拒绝策略,主要有四种
线程池的实际运用
创建一个线程池,由于线程池是单例的,下面用的是最简单的饿汉式的方式
package com.luban.utils;
import org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean;
import java.util.concurrent.*;
public class ThreadPool {
/**
* 核心线程数
*/
private static final int CORE_POOL_SIZA =5;
/***
* 最大线程数
*/
private static final int MAXIMUM_POOL_SIZE=10;
/**
* 空闲线程存活时间
*/
private static final int KEEP_ALIVE_TIME=30*1000;
/**
* 任务队列的大小
*/
private static final int BLOCKING_QUEUE_SIZE=20;
/**
* 饿汉式初始化
*/
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZA, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.MICROSECONDS,
new LinkedBlockingDeque<>(BLOCKING_QUEUE_SIZE),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());
public static ThreadPoolExecutor getExecutor(){return executor;}
}
下面的代码为线程池在业务代码中的调用,其中用的是callable接口
package com.luban.service;
import com.luban.utils.ThreadPool;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class UserService {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//1.获取线程池
ThreadPoolExecutor executor= ThreadPool.getExecutor();
//2.并发执行,记录线程执行顺序的集合
ArrayList<Callable<Object>> tasks=new ArrayList<>();
Callable<Object> task1=()->{
return ""; //执行任务1,并返回结果
};
Callable<Object> task2=()->{
return "";
};
Callable<Object> task3=()->{
return "";
};
//将任务加入list集合中
tasks.add(task1);
tasks.add(task2);
tasks.add(task3);
//开始利用线程池执行各个任务
List<Future<Object>> futures= executor.invokeAll(tasks,2, TimeUnit.SECONDS);
//取出第一个任务,也就是task1
Future<Object> objectFuture = futures.get(0);
//取出第一个任务的返回值,注意,由于加入的时候是按照task1,task2,task3添加的,取出的时候也是有顺序的
Object o = objectFuture.get();
}
}