为线程池中的每个线程设置UncaughtExceptionHandler

参考了《java并发编程实战》P134内容

每当线程池需要创建一个线程时,都是通过调用线程工厂方法来完成的,默认的线程工厂方法将创建一个新的、非守护的线程,并且不包好特殊的配置信息。

如果你希望在线程运行之前、之后、或者运行中如果发生异常等情况作一些人工干预的话,可以自定义线程工厂。

示例:

 
import java.util.concurrent.atomic.*;
 
import java.util.logging.*;
 
 
 
public class MyAppThread extends Thread {
 
public static final String DEFAULT_NAME = "MyAppThread";
 
private static final AtomicInteger created = new AtomicInteger();
 
private static final AtomicInteger alive = new AtomicInteger();
 
private static final Logger log = Logger.getAnonymousLogger();
 
public MyAppThread(Runnable r) {
 
this(r, DEFAULT_NAME);
 
}
 
public MyAppThread(Runnable runnable, String name) {
 
super(runnable, name + "-" + created.incrementAndGet());
 
this.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
 
public void uncaughtException(Thread t,
 
Throwable e) {
 
log.log(Level.SEVERE, "UNCAUGHT in thread " + t.getName(), e);
 
}
 
});
 
}
 
public void run() {
 
System.out.println("Created " + getName());
 
try {
 
alive.incrementAndGet();
 
super.run();
 
} finally {
 
alive.decrementAndGet();
 
System.out.println("Exiting " + getName());
 
}
 
}
 
public static int getThreadsCreated() {
 
return created.get();
 
}
 
public static int getThreadsAlive() {
 
return alive.get();
 
}
 
}
 
 
 
import java.util.concurrent.*;
 
 
 
public class MyThreadFactory implements ThreadFactory {
 
private final String poolName;
 
public MyThreadFactory(String poolName) {
 
this.poolName = poolName;
 
}
 
public Thread newThread(Runnable runnable) {
 
return new MyAppThread(runnable, poolName);
 
}
 
}
 
 
 
测试类:
 
import java.util.concurrent.ExecutorService;
 
import java.util.concurrent.LinkedBlockingQueue;
 
import java.util.concurrent.ThreadPoolExecutor;
 
import java.util.concurrent.TimeUnit;
 
public class MyThreadFactoryClient {
 
public static void main(String[] args) {
 
ExecutorService pool = new ThreadPoolExecutor(3, 3, 0L,
 
TimeUnit.MICROSECONDS, new LinkedBlockingQueue<Runnable>(),
 
new MyThreadFactory("ZJH"));
 
for (int i = 0; i < 10; i++) {
 
pool.execute(new MyThread("" + i));
 
}
 
pool.shutdown();
 
}
 
static class MyThread extends Thread {
 
public String name;
 
public MyThread(String name) {
 
this.name = name;
 
}
 
public void run() {
 
if("5".equals(name)){
 
throw new NullPointerException("5 is null");
 
}
 
System.out.println("Thread-" + name + " is running.....");
 
try {
 
Thread.sleep(2000);
 
} catch (InterruptedException e) {
 
e.printStackTrace();
 
}
 
}
 
}
 
}
 
 
 
扩展ThreadPoolExecutor :
 
import java.util.concurrent.*;
 
import java.util.concurrent.atomic.*;
 
import java.util.logging.*;
 
 
 
public class TimingThreadPool extends ThreadPoolExecutor {
 
public TimingThreadPool() {
 
super(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
 
}
 
private final ThreadLocal<Long> startTime = new ThreadLocal<Long>();
 
private final AtomicLong numTasks = new AtomicLong();
 
private final AtomicLong totalTime = new AtomicLong();
 
protected void beforeExecute(Thread t, Runnable r) {
 
super.beforeExecute(t, r);
 
System.out.println(String.format("Thread %s: start %s", t, r));
 
startTime.set(System.nanoTime());
 
}
 
protected void afterExecute(Runnable r, Throwable t) {
 
try {
 
long endTime = System.nanoTime();
 
long taskTime = endTime - startTime.get();
 
numTasks.incrementAndGet();
 
totalTime.addAndGet(taskTime);
 
System.out.println(String.format("Thread %s: end %s, time=%dns",
 
t, r, taskTime));
 
} finally {
 
super.afterExecute(r, t);
 
}
 
}
 
protected void terminated() {
 
try {
 
System.out.println(String.format("Terminated: avg time=%dns",
 
totalTime.get() / numTasks.get()));
 
} finally {
 
super.terminated();
 
}
 
}
 
 
 
public static void main(String[] args) {
 
TimingThreadPool pool = new TimingThreadPool();
 
pool.execute(new Runnable(){
 
public void run() {
 
System.out.println(Thread.currentThread().getName());
 
try {
 
Thread.sleep(300);
 
} catch (InterruptedException e) {
 
e.printStackTrace();
 
}
 
}
 
});
 
pool.shutdown();
 
}
 
}
 

  

posted @ 2020-06-17 14:19  w'c's  阅读(1526)  评论(0编辑  收藏  举报