參考了《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();
}
}
