java.util.concurrent.ThreadFactory 例項講解
阿新 • • 發佈:2019-02-09
本文到例項中將講解一下如何使用ThreadFactory
介面。這個介面是Java自身提供的,使用者可以實現它自定義自己的執行緒啟動方式,可以設定執行緒名稱、型別以及優先順序等屬性。
ThreadFactory
vs Default ThreadFactory
:
在一個典型的Java ExecutorService程式中,其執行緒都需要被指定以何種形式執行,如果程式初始化ExecutorService
時沒有指定ThreadFactory
,程式會採用一個預設的ThreadFactory
來生成提交執行緒,但是對於一個嚴謹對程式來說,定義自己的ThreadFactory
永遠是個最佳選擇。Why??
- 設定更有描述意義的執行緒名稱。如果使用預設的
ThreadFactory
,它給執行緒起名字大概規律就是pool-m-thread-n這個樣子,如pool-1-thread-1。但是當你分析一個thread dump時,看著這樣的名字就很難知道執行緒的目的。所以使用一個有描述意義的執行緒名稱是分析追蹤問題的clue NO.1。 - 設定執行緒是否是守護執行緒,預設的
ThreadFactory
總是提交非守護執行緒 - 設定執行緒優先順序,預設
ThreadFactory
總是提交的一般優先順序執行緒
例子:
CustomThreadFactoryBuilder
類實現了一種優雅的Builder Mechanism
ThreadFactory
例項。ThreadFactory
介面中有一個接受Runnable
型別引數的方法newThread(Runnable r)
,你自己的factory邏輯就應該寫在這個方法中,去配置執行緒名稱、優先順序、守護執行緒狀態等屬性。
public class CustomThreadFactoryBuilder {
private String namePrefix = null;
private boolean daemon = false;
private int priority = Thread.NORM_PRIORITY;
public CustomThreadFactoryBuilder setNamePrefix(String namePrefix) {
if (namePrefix == null) {
throw new NullPointerException();
}
this.namePrefix = namePrefix;
return this;
}
public CustomThreadFactoryBuilder setDaemon(boolean daemon) {
this.daemon = daemon;
return this;
}
public CustomThreadFactoryBuilder setPriority(int priority) {
if (priority < Thread.MIN_PRIORITY){
throw new IllegalArgumentException(String.format(
"Thread priority (%s) must be >= %s", priority, Thread.MIN_PRIORITY));
}
if (priority > Thread.MAX_PRIORITY) {
throw new IllegalArgumentException(String.format(
"Thread priority (%s) must be <= %s", priority, Thread.MAX_PRIORITY));
}
this.priority = priority;
return this;
}
public ThreadFactory build() {
return build(this);
}
private static ThreadFactory build(CustomThreadFactoryBuilder builder) {
final String namePrefix = builder.namePrefix;
final Boolean daemon = builder.daemon;
final Integer priority = builder.priority;
final AtomicLong count = new AtomicLong(0);
/*
return new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable);
if (namePrefix != null) {
thread.setName(namePrefix + "-" + count.getAndIncrement());
}
if (daemon != null) {
thread.setDaemon(daemon);
}
if (priority != null) {
thread.setPriority(priority);
}
return thread;
}
};*/
//jdk8中還是優先使用lamb表示式
return (Runnable runnable) -> {
Thread thread = new Thread(runnable);
if (namePrefix != null) {
thread.setName(namePrefix + "-" + count.getAndIncrement());
}
if (daemon != null) {
thread.setDaemon(daemon);
}
/*
thread.setPriority(priority);
*/
return thread;
};
}
}
SimpleTask
類實現類Runnable介面,打印出了執行緒的執行屬性(名稱,優先順序等)。
public class SimpleTask implements Runnable {
private long sleepTime;
public SimpleTask(long sleepTime) {
super();
this.sleepTime = sleepTime;
}
@Override
public void run() {
while (true) {
try {
System.out.println("Simple task is running on "
+ Thread.currentThread().getName() + " with priority " + Thread.currentThread().getPriority());
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
CustomThreadFactoryDemo
類使用我們上面的CustomThreadFactoryBuilder
類建立類一個ThreadFactory
例項,又使用這個例項獲得類一個ExecutoryService
,這樣所有這個執行緒池中的執行緒都會按我們定義好的屬性被生成,下面程式碼中執行類三個SimpleTask。
public class CustomThreadFactoryDemo {
public static void main(String[] args) {
ThreadFactory customThreadfactory = new CustomThreadFactoryBuilder()
.setNamePrefix("DemoPool-Thread").setDaemon(false)
.setPriority(Thread.MAX_PRIORITY).build();
ExecutorService executorService = Executors.newFixedThreadPool(3,
customThreadfactory);
// Create three simple tasks with 1000 ms sleep time
SimpleTask simpleTask1 = new SimpleTask(1000);
SimpleTask simpleTask2 = new SimpleTask(1000);
SimpleTask simpleTask3 = new SimpleTask(1000);
// Execute three simple tasks with 1000 ms sleep time
executorService.execute(simpleTask1);
executorService.execute(simpleTask2);
executorService.execute(simpleTask3);
}
}
輸出:
Simple task is running on DemoPool-Thread-0 with priority 10
Simple task is running on DemoPool-Thread-1 with priority 10
Simple task is running on DemoPool-Thread-2 with priority 10
Simple task is running on DemoPool-Thread-0 with priority 10
Simple task is running on DemoPool-Thread-1 with priority 10
Simple task is running on DemoPool-Thread-2 with priority 10
Simple task is running on DemoPool-Thread-0 with priority 10
Simple task is running on DemoPool-Thread-1 with priority 10
Simple task is running on DemoPool-Thread-2 with priority 10
Simple task is running on DemoPool-Thread-0 with priority 10
Simple task is running on DemoPool-Thread-1 with priority 10
Simple task is running on DemoPool-Thread-2 with priority 10