diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index 5381a7e39..52348a3fe 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -135,6 +135,7 @@ public class IrisSettings { @Data public static class IrisSettingsConcurrency { public int parallelism = -1; + public boolean useVirtualThreads = false; } @Data diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index 8496f924c..a54e457d0 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -19,6 +19,7 @@ package com.volmit.iris.core.pregenerator.methods; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.core.pregenerator.PregeneratorMethod; import com.volmit.iris.core.tools.IrisToolbelt; @@ -33,11 +34,13 @@ import org.bukkit.World; import java.util.ArrayList; import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class AsyncPregenMethod implements PregeneratorMethod { private final World world; - private final MultiBurst burst; + private final ExecutorService service; private final Semaphore semaphore; private final Map lastUse; @@ -47,7 +50,9 @@ public class AsyncPregenMethod implements PregeneratorMethod { } this.world = world; - burst = new MultiBurst("Iris Async Pregen", Thread.MIN_PRIORITY); + service = IrisSettings.get().getConcurrency().isUseVirtualThreads() ? + Executors.newVirtualThreadPerTaskExecutor() : + new MultiBurst("Iris Async Pregen", Thread.MIN_PRIORITY); semaphore = new Semaphore(256); this.lastUse = new KMap<>(); } @@ -103,7 +108,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { public void close() { semaphore.acquireUninterruptibly(256); unloadAndSaveAllChunks(); - burst.close(); + service.shutdown(); } @Override @@ -129,7 +134,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { } catch (InterruptedException e) { return; } - burst.complete(() -> completeChunk(x, z, listener)); + service.submit(() -> completeChunk(x, z, listener)); } @Override diff --git a/core/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java b/core/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java index cf840572e..6fbea21cd 100644 --- a/core/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java +++ b/core/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java @@ -24,12 +24,14 @@ import com.volmit.iris.core.service.PreservationSVC; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.M; import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import org.jetbrains.annotations.NotNull; +import java.util.Collection; import java.util.List; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicLong; -public class MultiBurst { +public class MultiBurst implements ExecutorService { public static final MultiBurst burst = new MultiBurst(); private final AtomicLong last; private final String name; @@ -144,6 +146,79 @@ public class MultiBurst { return getService().submit(o); } + @Override + public void shutdown() { + close(); + } + + @NotNull + @Override + public List shutdownNow() { + close(); + return List.of(); + } + + @Override + public boolean isShutdown() { + return service == null || service.isShutdown(); + } + + @Override + public boolean isTerminated() { + return service == null || service.isTerminated(); + } + + @Override + public boolean awaitTermination(long timeout, @NotNull TimeUnit unit) throws InterruptedException { + return service == null || service.awaitTermination(timeout, unit); + } + + @Override + public void execute(@NotNull Runnable command) { + getService().execute(command); + } + + @NotNull + @Override + public Future submit(@NotNull Callable task) { + return service.submit(task); + } + + @NotNull + @Override + public Future submit(@NotNull Runnable task, T result) { + return service.submit(task, result); + } + + @NotNull + @Override + public Future submit(@NotNull Runnable task) { + return service.submit(task); + } + + @NotNull + @Override + public List> invokeAll(@NotNull Collection> tasks) throws InterruptedException { + return service.invokeAll(tasks); + } + + @NotNull + @Override + public List> invokeAll(@NotNull Collection> tasks, long timeout, @NotNull TimeUnit unit) throws InterruptedException { + return service.invokeAll(tasks, timeout, unit); + } + + @NotNull + @Override + public T invokeAny(@NotNull Collection> tasks) throws InterruptedException, ExecutionException { + return service.invokeAny(tasks); + } + + @Override + public T invokeAny(@NotNull Collection> tasks, long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return service.invokeAny(tasks, timeout, unit); + } + public void close() { if (service != null) { service.shutdown();