mirror of
https://github.com/Minestom/Minestom.git
synced 2024-10-01 07:57:41 +02:00
Improve TickThread
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
06d8586f7f
commit
d9c32fe198
@ -39,8 +39,7 @@ public final class ThreadDispatcher {
|
|||||||
this.threads = new ArrayList<>(threadCount);
|
this.threads = new ArrayList<>(threadCount);
|
||||||
|
|
||||||
for (int i = 0; i < threadCount; i++) {
|
for (int i = 0; i < threadCount; i++) {
|
||||||
final TickThread.BatchRunnable batchRunnable = new TickThread.BatchRunnable();
|
final TickThread tickThread = new TickThread(phaser, i);
|
||||||
final TickThread tickThread = new TickThread(batchRunnable, i);
|
|
||||||
this.threads.add(tickThread);
|
this.threads.add(tickThread);
|
||||||
tickThread.start();
|
tickThread.start();
|
||||||
}
|
}
|
||||||
@ -98,7 +97,7 @@ public final class ThreadDispatcher {
|
|||||||
}
|
}
|
||||||
// Execute tick
|
// Execute tick
|
||||||
this.phaser.register();
|
this.phaser.register();
|
||||||
thread.runnable.startTick(phaser, () -> {
|
thread.startTick(() -> {
|
||||||
Acquirable.refreshEntries(chunkEntries);
|
Acquirable.refreshEntries(chunkEntries);
|
||||||
|
|
||||||
final ReentrantLock lock = thread.getLock();
|
final ReentrantLock lock = thread.getLock();
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
package net.minestom.server.thread;
|
package net.minestom.server.thread;
|
||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.utils.validate.Check;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.concurrent.Phaser;
|
import java.util.concurrent.Phaser;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@ -14,16 +12,33 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
* <p>
|
* <p>
|
||||||
* Created in {@link ThreadDispatcher}, and awaken every tick with a task to execute.
|
* Created in {@link ThreadDispatcher}, and awaken every tick with a task to execute.
|
||||||
*/
|
*/
|
||||||
public class TickThread extends Thread {
|
public final class TickThread extends Thread {
|
||||||
|
|
||||||
protected final BatchRunnable runnable;
|
|
||||||
private final ReentrantLock lock = new ReentrantLock();
|
private final ReentrantLock lock = new ReentrantLock();
|
||||||
|
private final Phaser phaser;
|
||||||
|
private volatile boolean stop;
|
||||||
|
private Runnable tickRunnable;
|
||||||
|
|
||||||
public TickThread(@NotNull BatchRunnable runnable, int number) {
|
public TickThread(Phaser phaser, int number) {
|
||||||
super(runnable, MinecraftServer.THREAD_NAME_TICK + "-" + number);
|
super(MinecraftServer.THREAD_NAME_TICK + "-" + number);
|
||||||
this.runnable = runnable;
|
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.
|
* Shutdowns the thread. Cannot be undone.
|
||||||
*/
|
*/
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
this.runnable.stop = true;
|
this.stop = true;
|
||||||
LockSupport.unpark(this);
|
LockSupport.unpark(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class BatchRunnable implements Runnable {
|
|
||||||
private static final AtomicReferenceFieldUpdater<BatchRunnable, TickContext> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user