diff --git a/core/src/main/java/github/nighter/smartspawner/spawner/lootgen/SpawnerLootGenerator.java b/core/src/main/java/github/nighter/smartspawner/spawner/lootgen/SpawnerLootGenerator.java index 2abbc756..166bea72 100644 --- a/core/src/main/java/github/nighter/smartspawner/spawner/lootgen/SpawnerLootGenerator.java +++ b/core/src/main/java/github/nighter/smartspawner/spawner/lootgen/SpawnerLootGenerator.java @@ -105,17 +105,17 @@ public void spawnLootToSpawner(SpawnerData spawner) { try { // Acquire dataLock to safely read spawn timing and configuration values - // Use tryLock with short timeout to avoid blocking + // Use longer timeout to wait for stack updates while maintaining timer sync boolean dataLockAcquired = false; try { - dataLockAcquired = spawner.getDataLock().tryLock(50, java.util.concurrent.TimeUnit.MILLISECONDS); + dataLockAcquired = spawner.getDataLock().tryLock(500, java.util.concurrent.TimeUnit.MILLISECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } if (!dataLockAcquired) { - // dataLock is held (likely stack size change), skip this cycle + // dataLock still held after timeout, skip this cycle to avoid blocking return; } @@ -175,9 +175,17 @@ public void spawnLootToSpawner(SpawnerData spawner) { // Re-acquire the lock for the update phase // This ensures the spawner hasn't been modified (like stack size changes) // between our async calculations and now - boolean updateLockAcquired = spawner.getLootGenerationLock().tryLock(); + // Use longer timeout to wait for concurrent operations while avoiding indefinite blocking + boolean updateLockAcquired = false; + try { + updateLockAcquired = spawner.getLootGenerationLock().tryLock(500, java.util.concurrent.TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + if (!updateLockAcquired) { - // Lock is held, stack size is changing, skip this update + // Lock still held after timeout, skip this update to avoid blocking main thread return; }