将 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 的名称,但我们可以根据需要修改它。