1:状态模式核心:

  • 上下文(Context):维护当前状态,委托行为给状态对象(如 Order类持有 State对象)。

  • 状态接口(State):定义不同状态下的行为(如 handle()方法)。

  • 具体状态(ConcreteState):实现状态接口,封装特定状态下的行为(如 PendingStatePaidState)。

2:Java中的应用

        2.1:ThreadPoolExecutor 的线程池状态管理

线程池在其生命周期的状态:

  • RUNNING:接受新任务,处理阻塞队列中的任务。
  • SHUTDOWN:不再接受新任务,但继续处理阻塞队列中的任务。
  • STOP:不再接受新任务,不再处理队列中的任务,并中断正在执行的任务。
  • TIDYING:所有任务已终止,任务计数为 0,即将调用 terminated() 钩子。
  • TERMINATEDterminated() 方法执行结束。

在 ThreadPoolExecutor 源码中,并没有像教科书那样定义一堆 RunningStateShutdownState 类,而是采用了一种 “位运算优化版的状态模式”。它将“运行状态”和“工作线程数量”压缩在一个 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 这样的类,但它完全符合状态模式的核心特征:

  1. 环境类 (Context)ThreadPoolExecutor 本身。
  2. 状态枚举RUNNINGSHUTDOWNSTOP 等充当了具体状态的角色。
  3. 行为依赖状态execute() 方法的行为完全取决于 ctl 的高位状态。
    • 如果是 RUNNING,执行提交逻辑。
    • 如果是 SHUTDOWN 或 STOP,执行拒绝策略 (reject)。
  4. 状态流转封闭:状态的改变只能通过 advanceRunState 这种受控方法进行,且遵循单向流转(RUNNING -> SHUTDOWN -> STOP -> TIDYING -> TERMINATED),外部无法随意篡改。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐