在应用中,一个线程池工具类,需要些什么,我整理了如下几点:
- 单例,而且是线程安全的单例
- 线程异常处理,当线程在实际执行过程中,如果出现异常,起码得记个log吧
- 线程池的设置,核心线程大小,阻塞队列,最大线程大小
/**
* 线程池工具类
*/
public class ThreadPoolUtils {
//核心线程数
private static final int CORE_POOL_SIZE = 5;
//最大线程数
private static final int MAX_POOL_ZISE = 200;
//存活时间
private static final Long KEEP_ALIVE_TIME = 60L;
//登记式单例
private static class ThreadPoolHolder {
private static final ThreadPoolExecutor executor =
new ThreadPoolExecutor( CORE_POOL_SIZE,
MAX_POOL_ZISE,
KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ExecutorService getExecutorService(){
return ThreadPoolHolder.executor;
}
/**
* 执行task
*/
public static void execute(Runnable task){
ThreadPoolHolder.executor.execute(getExcpThread(task));
}
public static void execute(Runnable runnable,Thread.UncaughtExceptionHandler excpHandler){
Thread thread = getExcpThread(runnable);
if(excpHandler != null)
thread.setUncaughtExceptionHandler(excpHandler);
ThreadPoolHolder.executor.execute(thread);
}
/**
* 默认线程异常处理器
*/
static class ThreadUncaughtException implements Thread.UncaughtExceptionHandler{
@Override
public void uncaughtException(Thread t, Throwable e) {
//log.error....
}
}
/**
* 获取带有异常处理的线程
*/
public static Thread getExcpThread(Runnable task){
Thread taskThread = null;
if(task instanceof Thread)
taskThread = (Thread)task;
else
taskThread = new Thread(task);
if(taskThread.getUncaughtExceptionHandler() == null)
taskThread.setUncaughtExceptionHandler(new ThreadUncaughtException());
return taskThread;
}
}
- 对于单例,这里采用登记式单例,jvm自有的线程安全,而且也是懒加载。当然double check + volatile也可。
- ThreadUncaughtException 默认的异常处理,只里面可以记一些log,报警,或者别的,根据业务而定
- getExcpThread(),一方面,如果线程没有设置异常处理器,则设置一个默认的,如果已经存在,则使用自己设置的。