状态模式(State Pattern)结合Java学习
·
1:状态模式核心:
-
上下文(Context):维护当前状态,委托行为给状态对象(如
Order类持有State对象)。 -
状态接口(State):定义不同状态下的行为(如
handle()方法)。 -
具体状态(ConcreteState):实现状态接口,封装特定状态下的行为(如
PendingState、PaidState)。
2:Java中的应用
2.1:ThreadPoolExecutor 的线程池状态管理
线程池在其生命周期的状态:
- RUNNING:接受新任务,处理阻塞队列中的任务。
- SHUTDOWN:不再接受新任务,但继续处理阻塞队列中的任务。
- STOP:不再接受新任务,不再处理队列中的任务,并中断正在执行的任务。
- TIDYING:所有任务已终止,任务计数为 0,即将调用
terminated()钩子。 - TERMINATED:
terminated()方法执行结束。
在 ThreadPoolExecutor 源码中,并没有像教科书那样定义一堆 RunningState, ShutdownState 类,而是采用了一种 “位运算优化版的状态模式”。它将“运行状态”和“工作线程数量”压缩在一个 int (ctl) 变量中,但在逻辑判断和行为分派上,严格遵循状态模式的思想。
源码片段:
// 1. 定义状态常量 (高位表示状态,低位表示线程数)
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
// Packing and unpacking ctl
// 2. 获取状态
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
// 3. 基于状态的行为分派 (核心逻辑)
public void execute(Runnable command) {
if (command == null) throw new NullPointerException();
int c = ctl.get();
// 【行为分派点】:根据当前状态决定行为
if (isRunning(c)) {
// 状态:RUNNING -> 行为:尝试添加线程或放入队列
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true)) return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
// ... 二次检查逻辑
} else if (!addWorker(command, false)) {
reject(command);
}
} else {
// 状态:非 RUNNING (SHUTDOWN, STOP 等) -> 行为:拒绝任务
reject(command);
}
}
// 4. 状态流转控制
public void shutdown() {
// 尝试将状态从 RUNNING 变为 SHUTDOWN
advanceRunState(SHUTDOWN);
interruptIdleWorkers();
}
public void shutdownNow() {
// 尝试将状态直接变为 STOP
advanceRunState(STOP);
interruptWorkers();
drainQueue();
}
// 内部状态推进逻辑 (模拟状态转换)
private boolean advanceRunState(int targetState) {
for (;;) {
int c = ctl.get();
// 如果当前状态已经比目标状态更“终态”,则不需要变更
if (runStateAtLeast(c, targetState))
return false;
// CAS 原子更新状态
if (ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
return true;
}
}
虽然它没有用 class RunningState 这样的类,但它完全符合状态模式的核心特征:
- 环境类 (Context):
ThreadPoolExecutor本身。 - 状态枚举:
RUNNING,SHUTDOWN,STOP等充当了具体状态的角色。 - 行为依赖状态:
execute()方法的行为完全取决于ctl的高位状态。- 如果是
RUNNING,执行提交逻辑。 - 如果是
SHUTDOWN或STOP,执行拒绝策略 (reject)。
- 如果是
- 状态流转封闭:状态的改变只能通过
advanceRunState这种受控方法进行,且遵循单向流转(RUNNING -> SHUTDOWN -> STOP -> TIDYING -> TERMINATED),外部无法随意篡改。
更多推荐


所有评论(0)