@@ -44,6 +44,7 @@ public class TickerTask implements Runnable {
44
44
45
45
/**
46
46
* This Map holds all currently actively ticking locations.
47
+ * The value of this map (Set entries) MUST be thread-safe and mutable.
47
48
*/
48
49
private final Map <ChunkPosition , Set <Location >> tickingLocations = new ConcurrentHashMap <>();
49
50
@@ -329,7 +330,7 @@ public Map<ChunkPosition, Set<Location>> getLocations() {
329
330
public Set <Location > getLocations (@ Nonnull Chunk chunk ) {
330
331
Validate .notNull (chunk , "The Chunk cannot be null!" );
331
332
332
- Set <Location > locations = tickingLocations .getOrDefault (new ChunkPosition (chunk ), new HashSet <> ());
333
+ Set <Location > locations = tickingLocations .getOrDefault (new ChunkPosition (chunk ), Collections . emptySet ());
333
334
return Collections .unmodifiableSet (locations );
334
335
}
335
336
@@ -343,7 +344,14 @@ public void enableTicker(@Nonnull Location l) {
343
344
Validate .notNull (l , "Location cannot be null!" );
344
345
345
346
ChunkPosition chunk = new ChunkPosition (l .getWorld (), l .getBlockX () >> 4 , l .getBlockZ () >> 4 );
346
- Set <Location > newValue = new HashSet <>();
347
+
348
+ /*
349
+ Note that all the values in #tickingLocations must be thread-safe.
350
+ Thus, the choice is between the CHM KeySet or a synchronized set.
351
+ The CHM KeySet was chosen since it at least permits multiple concurrent
352
+ reads without blocking.
353
+ */
354
+ Set <Location > newValue = ConcurrentHashMap .newKeySet ();
347
355
Set <Location > oldValue = tickingLocations .putIfAbsent (chunk , newValue );
348
356
349
357
/**
0 commit comments