适用源码:
9da0beb8e8fdad85f50d7039408c3d98494e91c7。本文记录源码行为,默认配置不等于实服配置。
设计状态:按现状编写,具体业务批准记录未逐项核定;开发状态:下述能力有实现证据,限制单列;验证状态:完成定向源码核对,未执行自动测试或实服验收。
执行上下文
| 工作 | 当前实例与约束 |
|---|---|
| 账本 SQL | PortTasks 单工作线程、有界队列256,通过 Future 续接 |
| Towny 适配 | PortTasks.global 切到 GlobalRegionScheduler,按适配器约定使用 |
| 玩家背包/UI | PortTasks.player 或 player.getScheduler,离线回调使 Future 结束 |
| 世界核心投放 | 异步加载目标区块后 RegionScheduler 执行 |
这些是源码执行边界,不证明 Towny 或其他插件任意调用都可全局线程安全。不要在区域线程 join/get 等待依赖区域任务完成。
命令与生产
FacilityCommand.run 把命令动作交给玩家 scheduler。FacilityInteractionService 识别核心后调度打开。
FacilityProductionService 以 inFlight 限制同设施;getChunkAtAsync 后续接区域投放,区块超时释放/失败按账本处理,不把“加载开始”视为成功。已加载与临时加载区块的释放分支不同。
制造与数据
ManufacturingService 在玩家区域操作真实背包;后台推进只处理独立的反序列化 ItemStack,不访问玩家、实体或世界。仓储 revision 和冻结快照处理并发,不能仅因使用 ConcurrentHashMap 就称事务安全。
SqliteDatabase 的 synchronized 保护连接,不自动赋予 Bukkit 对象线程归属;query 不创建事务。外部经济调用、SQL 和玩家存档必须分别确认。
Future、关闭与异常
PortTasks.player 在离线、关闭或调度返回空时异常结束;database 队列拒绝时返回失败 Future。ResourceScope 逆序关闭,执行器 shutdownNow 后不要继续受理新请求。
跨区域结果返回要重新核对页面会话和玩家状态,旧 Dialog 回调不能拿先前打开作为管理资格。未知结果不是明确失败,不能因为 Future 异常就无条件退款或重发。
尚未验证
真实区块切换、玩家离线、跨世界、服务关闭、队列饱和以及第三方插件互操作均需要隔离测试。战斗跨区域命中仍有未完成边界,不将本页视为全仓线程安全认证。
来源
代码根 folia_plugin/src/main/java/com/flrv/:infrastructure/scheduler/PortTasks.java、event/command/FacilityCommand.java#run、logic/facility/service/FacilityProductionService.java#schedule、logic/blacksmith/manufacturing/ManufacturingService.java#advance/skinTargets、bootstrap/ResourceScope.java、infrastructure/persistence/SqliteDatabase.java;docs/开发待办.md跨区域命中与实服验收章节。
相关:架构、驿站实现。