序言
在使用ThreadPoolExecutor 创建线程池过程中需要设置一个线程工厂.这里通过源码和Jdk提供的默认线程工厂来看下它都做了什么cuiyaonan2000@163.com
线程池
在创建线程池的时候,它有七个参数可以通过构造方法设置..
全参构造方法:
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
ThreadPoolExecutor 最少提供的参数的构造方法如下(即线程池允许你不设置 线程工厂 和 任务拒绝策略,并且提供默认的线程工厂和任务拒绝策略cuiyaonan2000@163.com):
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default thread factory and rejected execution handler.
* It may be more convenient to use one of the {@link Executors} factory
* methods instead of this general purpose constructor.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
可以看到默认的线程工厂ThreadFactory的实现类是Executors.defaultThreadFactory()提供的.
ThreadFactory
看下ThreadFactory的定义
/**
* An object that creates new threads on demand. Using thread factories
* removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread},
* enabling applications to use special thread subclasses, priorities, etc.
*
*
* The simplest implementation of this interface is just:
*
* {@code
* class SimpleThreadFactory implements ThreadFactory {
* public Thread newThread(Runnable r) {
* return new Thread(r);
* }
* }}
*
* The {@link Executors#defaultThreadFactory} method provides a more
* useful simple implementation, that sets the created thread context
* to known values before returning it.
* @since 1.5
* @author Doug Lea
*/
public interface ThreadFactory {
/**
* Constructs a new {@code Thread}. Implementations may also initialize
* priority, name, daemon status, {@code ThreadGroup}, etc.
*
* @param r a runnable to be executed by new thread instance
* @return constructed thread, or {@code null} if the request to
* create a thread is rejected
*/
Thread newThread(Runnable r);
}
从该接口的定义可知 使用线程工厂的方式的好处,关于线程组的可以参考: ThreadGroup_addunstarted-优快云博客
构造一个新的 Thread。实现还可以初始化 priority、name、daemon status、ThreadGroup 等。
Constructs a new {@code Thread}. Implementations may also initialize
* priority, name, daemon status, {@code ThreadGroup}, etc.即可以统一的管理多个线程,切方便处理.
DefaultThreadFactory
关于DefaultThreadFactory的设计思路如下:
Returns a default thread factory used to create new threads. This factory creates all new threads used by an Executor in the same ThreadGroup. If there is a SecurityManager, it uses the group of System. getSecurityManager, else the group of the thread invoking this defaultThreadFactory method. Each new thread is created as a non-daemon thread with priority set to the smaller of Thread. NORM_PRIORITY and the maximum priority permitted in the thread group. New threads have names accessible via Thread. getName of pool-N-thread-M, where N is the sequence number of this factory, and M is the sequence number of the thread created by this factory.
返回用于创建新线程的默认线程工厂。此工厂创建同一 ThreadGroup 中的 Executor 使用的所有新线程。如果存在 SecurityManager,则它使用 System.getSecurityManager,否则为调用此 defaultThreadFactory 方法的线程组。每个新线程都创建为非守护程序线程,其优先级设置为 Thread 中的较小者。NORM_PRIORITY 和线程组中允许的最大优先级。新线程具有可通过 Thread 访问的名称。getName of pool-N-thread-M,其中 N 是该工厂的序列号,M 是该工厂创建的线程的序列号。
关于守护线程
- 守护线程是一种特殊类型的线程,它在后台运行,并且仅在所有非守护线程结束后才退出。 通常用于执行一些清理工作或资源释放。 与非守护线程相比,守护线程的优先级较低。
- 当主线程执行结束后,所有在运行的子线程都直接结束,不管子任务是否完成。很多语言的垃圾收集器就运用了守护线程,去回收程序不再使用的垃圾内存。
- 非守护线程:如果主线程销毁,用户线程继续运行且互不影响。
- 守护线程当进程不存在或主线程停止,守护线程也会被停止。
- 守护线程不适合用于输入输出或计算等操作,因为用户线程执行完毕,程序就dead了,适用于辅助用户线程的场景,如JVM的垃圾回收,内存管理都是守护线程。
- 非守护线程:当所有非守护线程都终止时,JVM才会退出。若存在非守护线程仍在运行,JVM将等待它们完成。
- 守护线程:JVM不会等待守护线程完成。只要没有非守护线程在运行,JVM将立即退出。
创建实例如下所示:
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}