ForkJoinWorkerThreadFactory是ForkJoinPool的内部接口,用于创建工作线程ForkJoinWorkerThread对象。
public static interface ForkJoinWorkerThreadFactory {
/**
* Returns a new worker thread operating in the given pool.
*
* @param pool the pool this thread works in
* @return the new worker thread
* @throws NullPointerException if the pool is null
*/
public ForkJoinWorkerThread newThread(ForkJoinPool pool);
}
DefaultForkJoinWorkerThreadFactory是ForkJoinWorkerThreadFactory的默认实现类。
static final class DefaultForkJoinWorkerThreadFactory
implements ForkJoinWorkerThreadFactory {
public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
return new ForkJoinWorkerThread(pool);
}
}
InnocuousForkJoinWorkerThreadFactory实现了ForkJoinWorkerThreadFactory,当系统变量中有系统安全管理相关属性时,默认使用这个工厂创建工作线程。
static final class InnocuousForkJoinWorkerThreadFactory
implements ForkJoinWorkerThreadFactory {
/**
* An ACC to restrict permissions for the factory itself.
* The constructed workers have no permissions set.
*/
private static final AccessControlContext innocuousAcc;
static {
Permissions innocuousPerms = new Permissions();
innocuousPerms.add(modifyThreadPermission);
innocuousPerms.add(new RuntimePermission(
"enableContextClassLoaderOverride"));
innocuousPerms.add(new RuntimePermission(
"modifyThreadGroup"));
innocuousAcc = new AccessControlContext(new ProtectionDomain[] {
new ProtectionDomain(null, innocuousPerms)
});
}
public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
return (ForkJoinWorkerThread.InnocuousForkJoinWorkerThread)
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<ForkJoinWorkerThread>() {
public ForkJoinWorkerThread run() {
return new ForkJoinWorkerThread.
InnocuousForkJoinWorkerThread(pool);
}}, innocuousAcc);
}
}
tomcat中的SafeForkJoinWorkerThreadFactor类也实现了ForkJoinWorkerThreadFactory接口。
package org.apache.catalina.startup;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
public class SafeForkJoinWorkerThreadFactory implements ForkJoinWorkerThreadFactory {
public SafeForkJoinWorkerThreadFactory() {
}
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
return new SafeForkJoinWorkerThreadFactory.SafeForkJoinWorkerThread(pool);
}
private static class SafeForkJoinWorkerThread extends ForkJoinWorkerThread {
protected SafeForkJoinWorkerThread(ForkJoinPool pool) {
super(pool);
this.setContextClassLoader(ForkJoinPool.class.getClassLoader());
}
}
}
内部占位类,用于替换队列中join的任务。
static final class EmptyTask extends ForkJoinTask<Void> {
private static final long serialVersionUID = -7721805057305804111L;
EmptyTask() { status = ForkJoinTask.NORMAL; } // force done
public final Void getRawResult() { return null; }
public final void setRawResult(Void x) {}
public final boolean exec() { return true; }
}
为ForkJoinPool中的任务提供扩展管理并行数的接口,一般用在可能会阻塞的任务(如在Phaser中用于等待Phaser到下一个generation)。
public static interface ManagedBlocker {
/**
* Possibly blocks the current thread, for example waiting for
* a lock or condition.
*
* @return {@code true} if no additional blocking is necessary
* (i.e., if isReleasable would return true)
* @throws InterruptedException if interrupted while waiting
* (the method is not required to do so, but is allowed to)
*/
boolean block() throws InterruptedException;
/**
* Returns {@code true} if blocking is unnecessary.
* @return {@code true} if blocking is unnecessary
*/
boolean isReleasable();
}
ForkJoinPool的核心数据结构,本质上是work-stealing模式的双端任务队列,内部存放ForkJoinTask任务对象。作者不想多个WorkQueue实例或多个队列共享缓存行,@Contended注释会提醒JVM尝试将实例分开。使用@Contended注解修饰防止伪共享。
伪共享状态:缓存系统中是以缓存行(cache line)为单位存储的。缓存行是2的整数幂个连续字节,一般为32-256个字节。最常见的缓存行大小是64个字节。当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。
工作线程在运行中产生新的任务(通常是调用了fork方法)时,此时可以把WorkQueue的数据结构视为一个栈,新的任务会放入栈顶;工作线程在处理自己工作队列的任务时,按照FIFO的顺序。
工作线程在处理自己的工作队列的同时,会尝试窃取一个任务(可能是来自于刚刚提交到pool的任务,或是来自于其他工作线程的队列任务),此时可以把WorkQueue的数据结构视为一个FIFO的队列,窃取的任务位于其他线程的工作队列的队首。
// Constants shared across ForkJoinPool and WorkQueue
// 限定参数
//低位掩码,也是最大索引位
static final int SMASK = 0xffff;
//工作线程最大容量
static final int MAX_CAP = 0x7fff;
//偶数低位掩码
static final int EVENMASK = 0xfffe;
//workQueue数组最多64个槽位
static final int SQMASK = 0x007e;
// ctl子域和WorkQueue.scanState的掩码和标志位
//标记是否正在运行任务
static final int SCANNING = 1;
//失活状态 负数
static final int INACTIVE = 1 << 31;
//版本戳,防止ABA问题
static final int SS_SEQ = 1 << 16;
// ForkJoinPool.config和WorkQueue.config的配置信息标记
//模式掩码
static final int MODE_MASK = 0xffff << 16;
//LIFO队列
static final int LIFO_QUEUE = 0;
//FIFO队列
static final int FIFO_QUEUE = 1 << 16;
//共享模式队列,负数
static final int SHARED_QUEUE = 1 << 31;
//低位和高位掩码
private static final long SP_MASK = 0xffffffffL;
private static final long UC_MASK = ~SP_MASK;
//活跃线程数
private static final int AC_SHIFT = 48;
//活跃线程数增量
private static final long AC_UNIT = 0x0001L << AC_SHIFT;
//活跃线程数掩码
private static final long AC_MASK = 0xffffL << AC_SHIFT;
//工作线程数
private static final int TC_SHIFT = 32;
//工作线程数增量
private static final long TC_UNIT = 0x0001L << TC_SHIFT;
//工作线程数掩码
private static final long TC_MASK = 0xffffL << TC_SHIFT;
//创建工作线程标志
private static final long ADD_WORKER = 0x0001L << (TC_SHIFT + 15);
//线程池状态 SHUTDOWN状态为负数
private static final int RSLOCK = 1;
private static final int RSIGNAL = 1 << 1;
private static final int STARTED = 1 << 2;
private static final int STOP = 1 << 29;
private static final int TERMINATED = 1 << 30;
private static final int SHUTDOWN = 1 << 31;
// 实例字段
//主控制参数
volatile long ctl;
//运行状态锁
volatile int runState;
//并行度|模式
final int config
//用于生成工作线程索引
int indexSeed;
//主对象注册信息,WorkQueue
volatile WorkQueue[] workQueues;
//线程工厂
final ForkJoinWorkerThreadFactory factory;
//每个线程的异常信息
final UncaughtExceptionHandler ueh;
//用于创建工作线程的名称
final String workerNamePrefix;
//窃取任务总数,也可作为同步监视器
volatile AtomicLong stealCounter;
//静态初始化字段
//线程工厂
public static final ForkJoinWorkerThreadFactory
defaultForkJoinWorkerThreadFactory;
//启动或杀死线程的方法调用者的权限
private static final RuntimePermission modifyThreadPermission;
//公共静态pool
static final ForkJoinPool common;
//并行度,对应内部common池
static final int commonParallelism;
//备用线程数,在tryCompensate中使用
private static int commonMaxSpares;
//创建workerNamePrefix(工作线程名称前缀)时的序号
private static int poolNumberSequence;
//线程阻塞等待新的任务的超时值(以纳秒为单位),默认两秒
private static final long IDLE_TIMEOUT = 2000L * 1000L * 1000L;
//空闲超时时间,防止timer未命中
private static final long TIMEOUT_SLOP = 20L * 1000L * 1000L;
//默认备用线程数
private static final int DEFAULT_COMMON_MAX_SPARES = 256;
//阻塞前自旋的次数,用在awaitRunStateLock和awaitWork中
private static final int SPINS = 0;
//indexSeed的增量
private static final int SEED_INCREMENT = 0x9e3779b9;
ForkJoinPool的内部状态都是通过一个64位的long类型的变量ctl来存储,它由四个16位的子域组成:
//初始队列容量,2的整数次幂
static final int INITIAL_QUEUE_CAPACITY = 1 << 13;
//最大队列容量
static final int MAXIMUM_QUEUE_CAPACITY = 1 << 26; // 64M
//实例字段
//Worker状态,小于零:inactive;基数:scanning
volatile int scanState;
//记录前一个栈顶的ctl
int stackPred;
//窃取任务数
int nsteals;
//记录窃取者索引,初始为随机索引
int hint;
//池索引和模式
int config;
//1:locked;< 0:terminate;else 0
volatile int qlock;
//下一个pool操作的索引(栈底/队列头)
volatile int base;
//下一个push操作的索引(栈顶/队列尾)
int top;
//任务数组
ForkJoinTask<?>[] array;
//the containing pool (may be null)
final ForkJoinPool pool;
//当前工作队列的工作线程,共享模式下为null
final ForkJoinWorkerThread owner;
//调用park阻塞期间为owner,其他情况为null
volatile Thread parker;
//记录join过来的任务
volatile ForkJoinTask<?> currentJoin;
//记录从其他工作队列窃取过来的任务
volatile ForkJoinTask<?> currentSteal;