重写线程池ThreadFactory接口实现对线程异常的捕获

在开发过程中经常会用到线程池,但创建线程池的方法都比较简单,使用Executors来创建相应功能的线程池,常用的方法有这些。

1、 Executors.newFixedThreadPool(int nThreads);创建固定大小(nThreads,大小不能超过int的最大值)的线程池
2、Executors.newSingleThreadExecutor():创建大小为1的固定线程池。
3、Executors.newCachedThreadPool();创建corePoolSize为0,最大线程数为整型的最大数,线程keepAliveTime为1分钟,缓存任务的队列为SynchronousQueue的线程池。
4、Executors.newScheduledThreadPool(int corePoolSize):创建corePoolSize大小的线程池。

创建过程中最关注的参数是corePoolSize,maximumPoolSize已用来配置核心线程数和最大线程数,而KeepAliveTime,BlockingQueue,threadFactory则常被忽略,或者说不设置也无妨正常使用,但在一些特别情况下还是需要特别设置这些参数来启动线程池,这次主要来说明ThreadFactory的用处和自定义的配置。
ThreadFactory是一个接口,用户可以自己实现接口,也可以使用默认实现的,其内部只有一个方法。

public interface ThreadFactory {
    Thread newThread(Runnable r);
}

Executors中有默认实现

static class DefaultThreadFactory implements ThreadFactory {
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    DefaultThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() :
                              Thread.currentThread().getThreadGroup();
        namePrefix = "pool-" +
                      poolNumber.getAndIncrement() +
                     "-thread-";
    }

    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r,
                              namePrefix + threadNumber.getAndIncrement(),
                              0);
        if (t.isDaemon())
            t.setDaemon(false);
        if (t.getPriority() != Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}

newThread方法中对线程的命名和守护线程和线程优先级进行配置,这里我们可以加入更多自定义的功能,比如处理线程异常的方法还有在线程启动时打印日志等等,让线程池的创建和启动变得灵活可控。当异常发生时,及时打印异常情况然后通知其他服务或者重启线程进行重试等,但UncaughtExceptionHandler方法仅适用于execute()方法往线程池提交任务的情况,如果是适用submit方法则由回调get方法时来处理异常。

public class MyThreadFactory implements ThreadFactory {
    static final Logger LOGGER= Logger.getAnonymousLogger();
    private final UncaughtExceptionHandler ueh;
    private final AtomicInteger threadNum  = new AtomicInteger(1);
    private final String namePrefix;

    public MyThreadFactory() {
        this(new LoggingUncaughtExceptionHandler(),”threadFactory”);
    }
    
    public MyThreadFactory(UncaughtExceptionHandler ueh, String namePrefix) {
        this.ueh = ueh;
        this.namePrefix = namePrefix;
    }
    
    protected Thread doMakeThread(final Runnable r){
        return new Thread(r){
            @Override
            public String toString() {
                ThreadGroup group = getThreadGroup();
                String groupName = null == group?””:group.getName();
                return getClass().getSimpleName() +[+getName()+,+getId()+,+groupName+]@“+hashCode();
            }
        };
    }
    
    @Override
    public Thread newThread(Runnable r) {
        Thread t = doMakeThread(r);
        t.setUncaughtExceptionHandler(ueh);
        t.setName(namePrefix +-+threadNum.getAndIncrement());
        if (t.isDaemon()){
            t.setDaemon(false);
        }
        if (t.getPriority() != Thread.NORM_PRIORITY){
            t.setPriority(Thread.NORM_PRIORITY);
        }
        if (LOGGER.isLoggable(Level.FINE)){
            LOGGER.fine(new thread created”+t);
        }
        return t;
    }
    static class LoggingUncaughtExceptionHandler implements UncaughtExceptionHandler{
    
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println(“error”);
            LOGGER.log(Level.SEVERE,t+”terminated:,e);
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值