We use ExecutorService to assign threads from the internal thread pool or create them on-demand to perform tasks. Each ExecutorService has an ThreadFactory, but The ExecutorService will use always a default one if we don't set a custom one. Why we should do this?
Set a custom Daemon status, the default ThreadFactory produces non-daemon results.
Set priority to our threads, the default ThreadFactory set a medium priority to all their threads.
You can specify UncaughtExceptionHandler
for our thread using setUncaughtExceptionHandler()
on thread object. This gets called back when Thread's run method throws uncaught exception.
Here is a easy implementation of a ThreadFactory over a ThreadPool.
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);
}
This example just modify the name of the Thread with a counter, but we can modify it as long as we want.