為線程池中的每個線程設置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();
 
}
 
}
 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM