Merge pull request #172 from mlus-asuka/fix/169-bounded-thread-pool

Fix/169 bounded thread pool
This commit is contained in:
mlus 2026-05-10 00:06:51 +08:00 committed by GitHub
commit e15c9b335e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -51,9 +51,7 @@ import java.nio.file.Files;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class VanillaSync { public class VanillaSync {
@ -61,7 +59,20 @@ public class VanillaSync {
public static void register() { public static void register() {
} }
static ExecutorService executorService = Executors.newCachedThreadPool(new PSThreadPoolFactory("PlayerSync")); // FIX: Replace unbounded CachedThreadPool with a bounded ThreadPoolExecutor.
// CachedThreadPool creates unlimited threads with many players and slow DB queries,
// thread count can explode to 25000+ causing memory leaks and server crashes.
// Bounded pool: 2 core threads, max 8 threads, 30s keepalive, 256-task queue.
// If the queue is full, tasks run on the calling thread (CallerRunsPolicy) which
// provides natural backpressure instead of creating more threads.
static ExecutorService executorService = new ThreadPoolExecutor(
2, // core pool size
8, // maximum pool size
30L, TimeUnit.SECONDS, // idle thread keepalive
new LinkedBlockingQueue<>(256), // bounded work queue
new PSThreadPoolFactory("PlayerSync"),
new ThreadPoolExecutor.CallerRunsPolicy() // backpressure: run on caller thread if queue full
);
@SubscribeEvent @SubscribeEvent
public static void onDataPackSyncEvent(OnDatapackSyncEvent event) throws SQLException, IOException { public static void onDataPackSyncEvent(OnDatapackSyncEvent event) throws SQLException, IOException {