將 ThreadFactory 新增到 Executor

我們使用 ExecutorService 從內部執行緒池分配執行緒或按需建立它們以執行任務。每個 ExecutorService 都有一個 ThreadFactory,但如果我們不設定自定義的 ExecutorService,它將始終使用預設值。我們為什麼要這樣做?

  • 設定更具描述性的執行緒名稱。預設 ThreadFactory 以 pool-m-thread-n 的形式給出執行緒名稱,例如 pool-1-thread-1,pool-2-thread-1,pool-3-thread-1 等。如果你想嘗試除錯或監控某些東西,很難知道這些執行緒在做什麼

  • 設定自定義守護程式狀態,預設的 ThreadFactory 會生成非守護程式結果。

  • 設定我們的執行緒的優先順序,預設的 ThreadFactory 為其所有執行緒設定中等優先順序。

  • 你可以線上程物件上使用 setUncaughtExceptionHandler() 為我們的執行緒指定 UncaughtExceptionHandler。當 Thread 的 run 方法丟擲未捕獲的異常時,會回撥它。

這是一個通過 ThreadPool 輕鬆實現 ThreadFactory。

public class ThreadExecutorExample implements ThreadExecutor {
private static String TAG = "ThreadExecutorExample";
private static final int INITIAL_POOL_SIZE = 3;
private static final int MAX_POOL_SIZE = 5;

// Sets the amount of time an idle thread waits before terminating
private static final int KEEP_ALIVE_TIME = 10;

// Sets the Time Unit to seconds
private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;

private final BlockingQueue<Runnable> workQueue;

private final ThreadPoolExecutor threadPoolExecutor;

private final ThreadFactory threadFactory;
private ThreadPoolExecutor mThreadPoolExecutor;

public ThreadExecutorExample() {
    this.workQueue = new LinkedBlockingQueue<>();
    this.threadFactory = new CustomThreadFactory();
    this.threadPoolExecutor = new ThreadPoolExecutor(INITIAL_POOL_SIZE, MAX_POOL_SIZE,
            KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, this.workQueue, this.threadFactory);
}

public void execute(Runnable runnable) {
    if (runnable == null) {
        return;
    }
    this.threadPoolExecutor.execute(runnable);
}

private static class CustomThreadFactory implements ThreadFactory {
    private static final String THREAD_NAME = "thread_";
    private int counter = 0;

    @Override public Thread newThread(Runnable runnable) {
        return new Thread(runnable, THREAD_NAME + counter++);
    }
}
}

/**
 * Executor thread abstraction created to change the execution context from any thread from out ThreadExecutor.
 */
interface ThreadExecutor extends Executor {
    
    void execute(Runnable runnable);
    
}

這個例子只是用計數器修改 Thread 的名稱,但我們可以根據需要修改它。