为何自定义线程工厂(ThreadFactory)

JDK创建线程池如果没有指定线程工厂则会使用了默认的线程工厂(DefaultThreadFactory)

既然有默认工厂,为啥还要自定义线程工厂呢?原因如下:

1.可以设置有意见的线程名,这样方便我们开发调试,问题日志查找及定位。

2.可以设置守护线程。

3.设置线程优先级

4.处理未捕获的异常:

在执行一个任务时,线程可能会由于未捕获的异常而终止,默认处理是将异常打印到控制台。但这种处理方式有时并非你所想要的,存放如文件或者db会更合适。

所以可以在自定义的Thread Factory中指定UncaughtExceptionHandler,发生异常时便会按照预期的逻辑执行。

如下是我自定义的一个线程工厂:

package com.heling.juc.study;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @Auther: wangheling
* @Date: 2019/7/3 14:22
* @Description: 自定义线程工厂:设置线程名,守护线程,优先级以及UncaughtExceptionHandler
*/
@Slf4j
public class MyThreadFactory implements ThreadFactory {

    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;
    public MyThreadFactory(String namePrefix) {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() :
                Thread.currentThread().getThreadGroup();
        this.namePrefix = namePrefix + "-thread-";
    }
    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r,
                namePrefix + threadNumber.getAndIncrement(),
                0);
        //守护线程
        if (t.isDaemon())
            t.setDaemon(true);
        //线程优先级
        if (t.getPriority() != Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        /**
         * 处理未捕捉的异常
         */
        t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                System.out.println("do something to handle uncaughtException");
            }
        });
        return t;
    }

    //test client
    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(5, new MyThreadFactory("测试线程"));
        for (int i = 0; i < 10; i++) {
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    log.info("do something.........");
                    //未捕获的异常,走自定义的UncaughtExceptionHandler逻辑
                    int i = 1 / 0;
                }
            });
        }
        pool.shutdown();
    }
}

测试结果:

15:36:22.877 [测试线程-thread-4] INFO com.heling.juc.study.MyThreadFactory - do something.........

do something to handle uncaughtException

15:36:22.877 [测试线程-thread-1] INFO com.heling.juc.study.MyThreadFactory - do something.........

15:36:22.877 [测试线程-thread-2] INFO com.heling.juc.study.MyThreadFactory - do something.........

15:36:22.877 [测试线程-thread-3] INFO com.heling.juc.study.MyThreadFactory - do something.........

15:36:22.877 [测试线程-thread-5] INFO com.heling.juc.study.MyThreadFactory - do something.........

do something to handle uncaughtException

do something to handle uncaughtException

do something to handle uncaughtException

do something to handle uncaughtException

15:36:22.888 [测试线程-thread-6] INFO com.heling.juc.study.MyThreadFactory - do something.........

do something to handle uncaughtException

15:36:22.889 [测试线程-thread-7] INFO com.heling.juc.study.MyThreadFactory - do something.........

do something to handle uncaughtException

15:36:22.891 [测试线程-thread-10] INFO com.heling.juc.study.MyThreadFactory - do something.........

do something to handle uncaughtException

15:36:22.892 [测试线程-thread-9] INFO com.heling.juc.study.MyThreadFactory - do something.........

do something to handle uncaughtException

15:36:22.893 [测试线程-thread-8] INFO com.heling.juc.study.MyThreadFactory - do something.........

do something to handle uncaughtException

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值