1. 状态模式基础解析
状态模式是行为型设计模式的一种,它允许对象在内部状态改变时改变其行为,使对象看起来像是修改了它的类。这种模式特别适合处理那些在不同状态下有不同行为的对象,避免了大量的条件判断语句。
1.1 状态模式三大核心组件
在Java中实现状态模式通常包含以下三个核心组件:
- 上下文(Context):这是持有状态的对象,它会根据当前状态将行为委托给具体的状态对象。比如电商系统中的订单对象(Order),它会持有一个State接口的实例。
java复制public class Order {
private State currentState;
public void setState(State state) {
this.currentState = state;
}
public void handle() {
currentState.handle(this);
}
}
- 状态接口(State):定义所有具体状态类需要实现的方法。这些方法通常以上下文对象作为参数,使得状态对象可以操作上下文。
java复制public interface State {
void handle(Order order);
}
- 具体状态(ConcreteState):实现State接口,封装特定状态下的行为逻辑。例如:
java复制public class PendingState implements State {
@Override
public void handle(Order order) {
System.out.println("处理待支付订单");
// 业务逻辑...
order.setState(new PaidState());
}
}
public class PaidState implements State {
@Override
public void handle(Order order) {
System.out.println("处理已支付订单");
// 业务逻辑...
}
}
1.2 状态模式的优势
状态模式相比简单的条件判断有以下优势:
- 消除庞大的条件语句:将不同状态的行为分散到不同的状态类中,避免if-else或switch-case的膨胀
- 提高可扩展性:新增状态只需添加新的状态类,符合开闭原则
- 状态转换显式化:状态转换逻辑集中在状态类中,更易理解和维护
- 状态特定行为集中:每个状态的行为都封装在对应的类中,内聚性更高
提示:当发现一个类中有大量与对象状态相关的条件判断,且这些条件判断导致代码难以维护时,就应该考虑使用状态模式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Java中的状态模式实践
2.1 线程池的状态管理实现
Java标准库中的ThreadPoolExecutor是状态模式的经典应用,虽然它的实现方式与教科书示例有所不同,但完全符合状态模式的核心思想。
2.1.1 线程池的五种状态
ThreadPoolExecutor定义了五种状态:
- RUNNING:正常运行状态,接受新任务并处理队列中的任务
- SHUTDOWN:关闭状态,不再接受新任务,但会处理完队列中的任务
- STOP:停止状态,不再接受新任务,也不处理队列中的任务,并中断正在执行的任务
- TIDYING:整理状态,所有任务已终止,workerCount为0,将执行terminated()钩子
- TERMINATED:终止状态,terminated()方法已完成
2.1.2 状态压缩与位运算优化
ThreadPoolExecutor采用了一种高效的实现方式,将状态(runState)和工作线程数(workerCount)压缩到一个原子整型变量ctl中:
java复制private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING
