1.线程池创建可以通过JDK自带的工具类来进行创建:
//创建固定长度的线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
//创建单个线程的线程池
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
//可缓存的线程池
ExecutorService executorService2 = Executors.newCachedThreadPool();
//可调度任务的线程池
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
当然阿里规范中不建议这样来创建,因为创建的线程池,特别是后面两种线程池在创建的时候直接默认了非核心线程池为int的最大值.
2.出了上面的创建方式,我们还可以创建自定义的线程池:
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,4,
60, TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),
Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardOldestPolicy());
参数1:核心线程;
参数2:线程池最大线程数(核心线程+非核心线程);
参数3:非核心线程在空闲时的存活时间,一般来说非核心线程在空闲时间到了会被回收,也可以设置参数使得核心线程也回收;
参数4:非核心线程在空闲时的存活时间的时间单位;
参数5:阻塞队列,用于存放任务的队列,可以选择数组类型和链表类型;
参数6:线程工厂,负责创建线程;
参数7:拒绝策略,JDK默认实现了4种拒绝策略。
3.如何要自定义拒绝策略
public class MyRejectedExecutionHandler implements RejectedExecutionHandler {
/**
*
* @param r 当前拒绝的任务
* @param executor 当前线程池
*/
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
//获取线程池的阻塞队列
BlockingQueue<Runnable> queue = executor.getQueue();
//删除所有队列
queue.clear();
System.out.println("清除队列");
try {
//放入当前被拒绝的任务
queue.put(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyRejectedExecutionHandler implements RejectedExecutionHandler {
/**
*
* @param r 当前拒绝的任务
* @param executor 当前线程池
*/
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
//获取线程池的阻塞队列
BlockingQueue<Runnable> queue = executor.getQueue();
try {
//队尾插入该任务,如果队列满了,就等待60秒
queue.offer(r,60,TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}