不建议继承thread类封装工作流引擎,因其无法支持状态持久化、流程隔离、统一调度、生态集成及bpmn特性;应采用线程池+状态机+持久化存储+领域模型的轻量架构。

不建议通过继承 Thread 类来封装工作流引擎。
Java 中继承 Thread 类是一种非常底层且受限的并发建模方式,它与工作流引擎的核心需求(如状态持久化、任务编排、异常恢复、可视化、多实例、事务一致性、跨线程/进程协作等)存在根本性错位。用 Thread 子类模拟流程节点,本质上是把业务流程逻辑强行塞进线程生命周期里,会导致:
- 流程无法暂停、恢复、回滚或持久化(
Thread一旦结束就不可追溯) - 多个“流程实例”无法隔离管理(每个
Thread实例 ≠ 一个可追踪的流程实例) - 无法统一调度、监控、超时控制、依赖注入或日志审计
- 与 Spring、数据库、消息队列等生态完全脱节
- 极难支持并行网关、分支合并、补偿事务等标准 BPMN 特性
✅ 正确的技术路径是:基于线程池 + 状态机 + 持久化存储 + 领域模型,而非继承 Thread。
用状态机驱动流程生命周期
将每个流程实例抽象为一个带明确状态(如 CREATED → RUNNING → WAITING → COMPLETED → FAILED)的 POJO 对象:
- 定义
WorkflowInstance类,含 id、currentNodeId、variables、status、updatedAt 等字段 - 所有流程推进操作(如
triggerNext("approve"))只改变其状态和上下文,不绑定线程 - 状态变更通过事件发布(如
WorkflowEvent.PAUSED),由监听器决定是否提交到线程池执行下一步
用线程池解耦执行与调度
真正执行节点逻辑的,应是标准的 ExecutorService,而非自定义 Thread 子类:
- 定义
NodeHandler<t></t>接口,每个节点类型(审批、调用 API、写 DB)实现自己的处理器 - 调度器(
WorkflowScheduler)根据流程实例当前状态,从注册表中查出对应NodeHandler,提交到共享线程池执行 - 支持异步回调(
CompletableFuture)、超时熔断(Future.get(30, SECONDS))、重试策略
轻量级持久化只需三张表
不依赖 Activiti/Camunda 的复杂 schema,自己维护最小必要数据:
-
workflow_instance:主键 id、definition_key、status、start_time、end_time、variables(JSON 字段) -
workflow_execution_log:trace_id、node_id、status、input/output(JSON)、cost_ms、error_stack -
workflow_definition:流程定义 JSON(类似 YAML 描述节点顺序、条件表达式、handler 类名)
用 MyBatis 或 JdbcTemplate 即可完成 CRUD,无需引入 ORM 复杂度。
流程定义用 DSL 而非代码硬编码
避免在 Java 类中写死流程逻辑。推荐定义简洁的内部 DSL:
flow("leave-apply")
.startWith("fill-form")
.then("manager-approve").when("user.level >= 2")
.then("hr-check").always()
.onFail("notify-failed").retry(2)
.end();
运行时解析该 DSL,生成内存中的 WorkflowGraph(有向无环图),再结合 WorkflowInstance 状态做节点匹配与跳转。
不复杂但容易忽略:真正的“轻量”,不在于少写几行代码,而在于不把线程当流程、不把类继承当架构、不把内存变量当状态事实。用好 JDK 并发工具包 + 简单持久化 + 显式状态管理,就能做出稳定、可观测、易调试的自研工作流核心。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











