diff --git a/src/main/java/net/minestom/server/thread/ThreadDispatcher.java b/src/main/java/net/minestom/server/thread/ThreadDispatcher.java index 213354474..2fa355de0 100644 --- a/src/main/java/net/minestom/server/thread/ThreadDispatcher.java +++ b/src/main/java/net/minestom/server/thread/ThreadDispatcher.java @@ -39,8 +39,7 @@ public final class ThreadDispatcher { this.threads = new ArrayList<>(threadCount); for (int i = 0; i < threadCount; i++) { - final TickThread.BatchRunnable batchRunnable = new TickThread.BatchRunnable(); - final TickThread tickThread = new TickThread(batchRunnable, i); + final TickThread tickThread = new TickThread(phaser, i); this.threads.add(tickThread); tickThread.start(); } @@ -98,7 +97,7 @@ public final class ThreadDispatcher { } // Execute tick this.phaser.register(); - thread.runnable.startTick(phaser, () -> { + thread.startTick(() -> { Acquirable.refreshEntries(chunkEntries); final ReentrantLock lock = thread.getLock(); diff --git a/src/main/java/net/minestom/server/thread/TickThread.java b/src/main/java/net/minestom/server/thread/TickThread.java index 1b29fe059..1bb6909f6 100644 --- a/src/main/java/net/minestom/server/thread/TickThread.java +++ b/src/main/java/net/minestom/server/thread/TickThread.java @@ -1,11 +1,9 @@ package net.minestom.server.thread; import net.minestom.server.MinecraftServer; -import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.NotNull; import java.util.concurrent.Phaser; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReentrantLock; @@ -14,16 +12,33 @@ import java.util.concurrent.locks.ReentrantLock; *

* Created in {@link ThreadDispatcher}, and awaken every tick with a task to execute. */ -public class TickThread extends Thread { - - protected final BatchRunnable runnable; +public final class TickThread extends Thread { private final ReentrantLock lock = new ReentrantLock(); + private final Phaser phaser; + private volatile boolean stop; + private Runnable tickRunnable; - public TickThread(@NotNull BatchRunnable runnable, int number) { - super(runnable, MinecraftServer.THREAD_NAME_TICK + "-" + number); - this.runnable = runnable; + public TickThread(Phaser phaser, int number) { + super(MinecraftServer.THREAD_NAME_TICK + "-" + number); + this.phaser = phaser; + } - this.runnable.setLinkedThread(this); + @Override + public void run() { + while (!stop) { + final Runnable localRunnable = tickRunnable; + if (localRunnable != null) { + localRunnable.run(); + this.tickRunnable = null; + this.phaser.arriveAndDeregister(); + } + LockSupport.park(this); + } + } + + void startTick(@NotNull Runnable runnable) { + this.tickRunnable = runnable; + LockSupport.unpark(this); } /** @@ -39,52 +54,7 @@ public class TickThread extends Thread { * Shutdowns the thread. Cannot be undone. */ public void shutdown() { - this.runnable.stop = true; + this.stop = true; LockSupport.unpark(this); } - - protected static class BatchRunnable implements Runnable { - private static final AtomicReferenceFieldUpdater CONTEXT_UPDATER = - AtomicReferenceFieldUpdater.newUpdater(BatchRunnable.class, TickContext.class, "tickContext"); - - private volatile boolean stop; - private TickThread tickThread; - - private volatile TickContext tickContext; - - @Override - public void run() { - Check.notNull(tickThread, "The linked BatchThread cannot be null!"); - while (!stop) { - final TickContext localContext = tickContext; - // The context is necessary to control the tick rates - if (localContext != null) { - // Execute tick - CONTEXT_UPDATER.compareAndSet(this, localContext, null); - localContext.runnable.run(); - localContext.phaser.arriveAndDeregister(); - } - LockSupport.park(this); - } - } - - protected void startTick(@NotNull Phaser phaser, @NotNull Runnable runnable) { - this.tickContext = new TickContext(phaser, runnable); - LockSupport.unpark(tickThread); - } - - private void setLinkedThread(TickThread tickThread) { - this.tickThread = tickThread; - } - } - - private static class TickContext { - private final Phaser phaser; - private final Runnable runnable; - - private TickContext(@NotNull Phaser phaser, @NotNull Runnable runnable) { - this.phaser = phaser; - this.runnable = runnable; - } - } }