一、初始线程池
线程池是一项线程复用技术,通过在程序内部维持一定数量的线程来提高性能。在Java中,使用接口ExecutorService表示线程池。
二、创建线程池
方式一: 创建ThreadPoolExecutor对象
//构造器
ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
- 参数corePoolSize表示核心线程数。
- 线程主要负责运算:核心线程数=CPU核数+1
- 线程主要负责IO操作:核心线程数=CPU核数*2
- 参数maximumPoolSize表示最大线程数。(最大线程数=核心线程数+临时线程数)
- 参数keepAliveTime表示临时线程的最大空闲时间。
- 参数unit表示临时线程对最大空闲时间的单位。
- 参数workQueue表示任务队列。
- new ArrayBlockingQueue(int capacity)表示创建一个长度为capacity的数组队列
- new linkedBlockingQueue( )表示创建一个链表队列
- 参数threadFactory表示临时线程的工厂对象。
- Executors.defaultThreadFactory( )返回创建临时线程的默认工厂对象
- 参数handler表示线程池的拒绝策略。(ThreadPoolExecutor的内部类提供了拒绝策略)
- ThreadPoolExecutor.AbortPolicy(默认策略):抛出异常
- ThreadPoolExecutor.CallerRunsPolicy:主线程直接调用线程的run( )方法执行
- ThreadPoolExecutor.DiscardOldestPolicy:将任务队列中等待时间最长的任务丢弃,新任务入队列
- ThreadPoolExecutor.DiscardPolicy:直接丢弃
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
int corePoolSize=3;
int maximumPoolSize=5;
long keepAliveTime=60;
//创建线程池
ExecutorService pool=new ThreadPoolExecutor(corePoolSize,
maximumPoolSize,
keepAliveTime,
TimeUnit.MINUTES,
new ArrayBlockingQueue<>(10),
new ThreadPoolExecutor.AbortPolicy());
//执行Runnable任务
pool.execute(new MyRunnable());
//执行Callable任务
Future<String> future = pool.submit(new MyCallable());
}
}
何时创建临时线程?
当新任务提交,核心线程忙碌,任务队列已满,存在可创建的临时线程时创建。
何时启动拒绝策略?
当新任务提交,临时线程与核心线程忙碌,任务队列已满,不存在可创建的临时线程时启动拒绝策略。
方式二:使用Executors工具类创建线程池
//创建固定线程数量的线程池
public static ExecutorService newFixedThreadPool(int nThreads)
//创建线程数量为1的线程池
public static ExecutorService newSingleThreadExecutor()
//创建线程数量随任务增多而增多的线程池,线程空闲60s被回收
public static ExecutorService newCacheThreadPool()
工具类Executors中创建线程池的方法底层都是通过ThreadPoolExecutor类创建线程池。