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