import javax.annotation.PreDestroy;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 自定义线程池
*/
public class ThreadPool {
/**
* 自定义线程池
* @return
*/
private final int CORE_POOL_SIZE = 5; // 核心线程数
private final int MAXIMUM_POOL_SIZE = 20; //最大线程数量
private final long KEEP_ALIVE_TIME = 60; //空闲时间
private ThreadPoolExecutor threadPoolExecutor;//自定义线程池
public ThreadPoolExecutor getThreadPoolExecutor() {
return threadPoolExecutor;
}
/**
* 静态内部类单例实现
*/
private static ThreadPool threadPool = new ThreadPool();
public static ThreadPool getInstance(){
return threadPool;
}
private ThreadPool(){
threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,MAXIMUM_POOL_SIZE,KEEP_ALIVE_TIME, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(5500),new ExecutorThreadFactory(), new ExecutorRejectedExecutionHandler());
}
/** ----------------- 构建线程池的关键参数 -----------------**/
/**
* BlockingQueue<Runnable> workQueue 任务阻塞队列
*/
/**
* 线程工厂用于创建线程
*
*/
private static class ExecutorThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final String namePrefix;
ExecutorThreadFactory(String name){
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
//此时namePrefix就是 name + 第几个用这个工厂创建线程池的
this.namePrefix = name + poolNumber.getAndIncrement();
System.out.println("--------------------创建新的线程池");
}
private ExecutorThreadFactory() {
//默认namePrefix = default-name-pool
this("default-name-pool");
}
@Override
public Thread newThread(Runnable r) {
//此时线程的名字 就是 namePrefix + -thread- + 这个线程池中第几个执行的线程
Thread t = new Thread(group, r, namePrefix + "-thread-"+threadNumber.getAndIncrement(),
0);
// if (t.isDaemon())
// t.setDaemon(false);
// 设置线程优先级(不一定起作用)
// if (t.getPriority() != Thread.NORM_PRIORITY)
// t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
/**
* 拒绝处理任务时的策略
* ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
* ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
* rejectedExecution 空方法
* ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
* if (!executor.isShutdown()) {
* //移除队头元素
* executor.getQueue().poll();
* //再尝试入队
* executor.execute(r);
* }
* ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
* if (!executor.isShutdown()) {
* //直接执行run方法
* r.run();
* }
*/
private class ExecutorRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 移除该任务 并抛出异常
executor.remove(r);
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
executor.toString());
}
}
/** ----------------- 构建线程池的关键参数 -----------------**/
/**
* 结束线程 : 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
*/
public @PreDestroy void shutdown() {
threadPoolExecutor.shutdown();
}
public static void main(String[] args) {
ThreadPool threadPool = ThreadPool.getInstance();
}
}
线程池详细介绍:https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html