diff --git a/src/main/java/dev/modzuozhi/core/compat/DistanceManagerLock.java b/src/main/java/dev/modzuozhi/core/compat/DistanceManagerLock.java new file mode 100644 index 0000000..9a6237d --- /dev/null +++ b/src/main/java/dev/modzuozhi/core/compat/DistanceManagerLock.java @@ -0,0 +1,22 @@ +package dev.modzuozhi.core.compat; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * DistanceManager ticket 表的共享锁。 + *
+ * DR 让维度 tick 跑在独立线程后,多个线程会并发修改 {@code DistanceManager.tickets} + * ({@code Long2ObjectOpenHashMap},非线程安全)。{@link dev.modzuozhi.mixin.DistanceManagerMixin} + * 用它串行化所有 ticket 写路径。 + *
+ * 跨 mod 可见性:ServerWarashi 的 {@code TicketScanService} 在主线程遍历同一张 ticket 表 + * (性能采样归属快照),若不持同一把锁,遍历会与维度线程的写并发 → fastutil fail-fast 迭代器 + * NPE。因此本锁公开,warashi 通过反射获取并共用,实现「读-写互斥」。 + */ +public final class DistanceManagerLock { + /** 所有 DistanceManager ticket 读/写路径共用的锁。 */ + public static final ReentrantLock LOCK = new ReentrantLock(); + + private DistanceManagerLock() { + } +} \ No newline at end of file diff --git a/src/main/java/dev/modzuozhi/mixin/DistanceManagerMixin.java b/src/main/java/dev/modzuozhi/mixin/DistanceManagerMixin.java index 68c96f5..c7b9b5a 100644 --- a/src/main/java/dev/modzuozhi/mixin/DistanceManagerMixin.java +++ b/src/main/java/dev/modzuozhi/mixin/DistanceManagerMixin.java @@ -10,8 +10,7 @@ import net.minecraft.server.level.Ticket; import net.minecraft.world.level.ChunkPos; import org.spongepowered.asm.mixin.Mixin; -import java.util.concurrent.locks.ReentrantLock; - +import dev.modzuozhi.core.compat.DistanceManagerLock; /** * {@code DistanceManager}(区块 ticket 调度)并发保护。 *
@@ -26,7 +25,7 @@ import java.util.concurrent.locks.ReentrantLock;
*/
@Mixin(DistanceManager.class)
public class DistanceManagerMixin {
- private static final ReentrantLock LOCK = new ReentrantLock();
+ private static final java.util.concurrent.locks.ReentrantLock LOCK = DistanceManagerLock.LOCK;
@WrapMethod(method = "addTicket")
private void modzuozhi_lockAddTicket(long chunkPos, Ticket> ticket, Operation