如何写好一个线程池(java)

在应用中,一个线程池工具类,需要些什么,我整理了如下几点:

  • 单例,而且是线程安全的单例
  • 线程异常处理,当线程在实际执行过程中,如果出现异常,起码得记个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(),一方面,如果线程没有设置异常处理器,则设置一个默认的,如果已经存在,则使用自己设置的。

猜你喜欢

转载自blog.csdn.net/u014801432/article/details/81290085