mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-11-29 05:55:36 +01:00
Handful of small fixes.
* Fix material loading from config requiring minecraft: namespace. * Fix disallowed-lightning blocks. Lightning entities are weird. * Fix /wg reload overwriting config changes. * General around thread usage/naming/shutdown. If anyone was actually making their own managers/indices you deserve to break.
This commit is contained in:
parent
b7ad0257b7
commit
3468e3d47e
@ -60,7 +60,6 @@ public void copyDefaults() {
|
||||
@Override
|
||||
public void unload() {
|
||||
worlds.clear();
|
||||
getConfig().save();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -69,6 +68,7 @@ public void postLoad() {
|
||||
for (World world : WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds()) {
|
||||
get(world);
|
||||
}
|
||||
getConfig().save();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,6 +97,10 @@ public void onChunkUnload(ChunkUnloadEvent event) {
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, cache::invalidateAll, CACHE_INVALIDATION_INTERVAL, CACHE_INVALIDATION_INTERVAL);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
container.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected RegionManager load(World world) {
|
||||
|
@ -130,7 +130,7 @@ public void load() {
|
||||
@Override
|
||||
public void unload() {
|
||||
configuration.unload();
|
||||
regionContainer.unload();
|
||||
regionContainer.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -594,7 +594,7 @@ public void onBlockFromTo(BlockFromToEvent event) {
|
||||
Material toType = to.getType();
|
||||
|
||||
// Liquids pass this event when flowing to solid blocks
|
||||
if (toType.isSolid() && Materials.isLiquid(fromType)) {
|
||||
if (Materials.isLiquid(fromType) && toType.isSolid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -93,8 +95,12 @@ public void onLightningStrike(LightningStrikeEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getWorld()));
|
||||
|
||||
if (wcfg.disallowedLightningBlocks.size() > 0) {
|
||||
Material targetId = event.getLightning().getLocation().getBlock().getType();
|
||||
if (!wcfg.disallowedLightningBlocks.isEmpty()) {
|
||||
final Block target = event.getLightning().getLocation().getBlock();
|
||||
Material targetId = target.getType();
|
||||
if (targetId == Material.AIR) {
|
||||
targetId = target.getRelative(BlockFace.DOWN).getType();
|
||||
}
|
||||
if (wcfg.disallowedLightningBlocks.contains(BukkitAdapter.asBlockType(targetId).getId())) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
@ -77,7 +77,8 @@ private WorldGuard() {
|
||||
}
|
||||
|
||||
public void setup() {
|
||||
executorService = MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 20));
|
||||
executorService = MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 20,
|
||||
"WorldGuard Task Executor - %s"));
|
||||
|
||||
File cacheDir = new File(getPlatform().getConfigDir().toFile(), "cache");
|
||||
cacheDir.mkdirs();
|
||||
|
@ -19,15 +19,21 @@
|
||||
|
||||
package com.sk89q.worldguard.config;
|
||||
|
||||
import com.sk89q.worldedit.util.report.Unreported;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.blacklist.Blacklist;
|
||||
import com.sk89q.worldedit.util.report.Unreported;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
@ -55,7 +61,8 @@ public abstract class WorldConfiguration {
|
||||
|
||||
protected File blacklistFile;
|
||||
|
||||
@Unreported protected Blacklist blacklist;
|
||||
@Unreported
|
||||
protected Blacklist blacklist;
|
||||
|
||||
public boolean boundedLocationFlags;
|
||||
public boolean useRegions;
|
||||
@ -173,49 +180,63 @@ public Blacklist getBlacklist() {
|
||||
}
|
||||
|
||||
public List<String> convertLegacyItems(List<String> legacyItems) {
|
||||
return legacyItems.stream().map(this::convertLegacyItem).collect(Collectors.toList());
|
||||
return legacyItems.stream().map(this::convertLegacyItem).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public String convertLegacyItem(String legacy) {
|
||||
String item = legacy;
|
||||
String[] splitter = legacy.split(":", 2);
|
||||
try {
|
||||
String[] splitter = item.split(":", 2);
|
||||
int id = 0;
|
||||
byte data = 0;
|
||||
int id;
|
||||
byte data;
|
||||
if (splitter.length == 1) {
|
||||
id = Integer.parseInt(item);
|
||||
id = Integer.parseInt(splitter[0]);
|
||||
data = 0;
|
||||
} else {
|
||||
id = Integer.parseInt(splitter[0]);
|
||||
data = Byte.parseByte(splitter[1]);
|
||||
}
|
||||
item = LegacyMapper.getInstance().getItemFromLegacy(id, data).getId();
|
||||
} catch (Throwable e) {
|
||||
ItemType legacyItem = LegacyMapper.getInstance().getItemFromLegacy(id, data);
|
||||
if (legacyItem != null) {
|
||||
return legacyItem.getId();
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
final ItemType itemType = ItemTypes.get(legacy);
|
||||
if (itemType != null) {
|
||||
return itemType.getId();
|
||||
}
|
||||
|
||||
return item;
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> convertLegacyBlocks(List<String> legacyBlocks) {
|
||||
return legacyBlocks.stream().map(this::convertLegacyBlock).collect(Collectors.toList());
|
||||
return legacyBlocks.stream().map(this::convertLegacyBlock).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public String convertLegacyBlock(String legacy) {
|
||||
String block = legacy;
|
||||
String[] splitter = legacy.split(":", 2);
|
||||
try {
|
||||
String[] splitter = block.split(":", 2);
|
||||
int id = 0;
|
||||
byte data = 0;
|
||||
int id;
|
||||
byte data;
|
||||
if (splitter.length == 1) {
|
||||
id = Integer.parseInt(block);
|
||||
id = Integer.parseInt(splitter[0]);
|
||||
data = 0;
|
||||
} else {
|
||||
id = Integer.parseInt(splitter[0]);
|
||||
data = Byte.parseByte(splitter[1]);
|
||||
}
|
||||
block = LegacyMapper.getInstance().getBlockFromLegacy(id, data).getBlockType().getId();
|
||||
} catch (Throwable e) {
|
||||
BlockState legacyBlock = LegacyMapper.getInstance().getBlockFromLegacy(id, data);
|
||||
if (legacyBlock != null) {
|
||||
return legacyBlock.getBlockType().getId();
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
final BlockType blockType = BlockTypes.get(legacy);
|
||||
if (blockType != null) {
|
||||
return blockType.getId();
|
||||
}
|
||||
|
||||
return block;
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getMaxRegionCount(LocalPlayer player) {
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.managers;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.index.ChunkHashTable;
|
||||
import com.sk89q.worldguard.protection.managers.index.ConcurrentRegionIndex;
|
||||
@ -29,15 +31,22 @@
|
||||
import com.sk89q.worldguard.util.Normal;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Manages different {@link RegionManager}s for different worlds or dimensions.
|
||||
*
|
||||
@ -52,8 +61,8 @@ public class RegionContainerImpl {
|
||||
private final ConcurrentMap<Normal, RegionManager> mapping = new ConcurrentHashMap<>();
|
||||
private final Object lock = new Object();
|
||||
private final RegionDriver driver;
|
||||
private final Supplier<? extends ConcurrentRegionIndex> indexFactory = new ChunkHashTable.Factory(new PriorityRTreeIndex.Factory());
|
||||
private final Timer timer = new Timer();
|
||||
private final Function<String, ? extends ConcurrentRegionIndex> indexFactory = new ChunkHashTable.Factory(new PriorityRTreeIndex.Factory());
|
||||
private final Timer timer = new Timer("WorldGuard Region I/O");
|
||||
private final FlagRegistry flagRegistry;
|
||||
|
||||
private final Set<Normal> failingLoads = new HashSet<>();
|
||||
@ -182,6 +191,14 @@ public void unloadAll() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable completely.
|
||||
*/
|
||||
public void shutdown() {
|
||||
timer.cancel();
|
||||
unloadAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region manager for the given world name.
|
||||
*
|
||||
|
@ -37,6 +37,7 @@
|
||||
import com.sk89q.worldguard.protection.util.RegionCollectionConsumer;
|
||||
import com.sk89q.worldguard.util.Normal;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -47,9 +48,7 @@
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* A region manager holds the regions for a world.
|
||||
@ -57,7 +56,7 @@
|
||||
public final class RegionManager {
|
||||
|
||||
private final RegionDatabase store;
|
||||
private final Supplier<? extends ConcurrentRegionIndex> indexFactory;
|
||||
private final Function<String, ? extends ConcurrentRegionIndex> indexFactory;
|
||||
private final FlagRegistry flagRegistry;
|
||||
private ConcurrentRegionIndex index;
|
||||
|
||||
@ -68,14 +67,14 @@ public final class RegionManager {
|
||||
* @param indexFactory the factory for creating new instances of the index
|
||||
* @param flagRegistry the flag registry
|
||||
*/
|
||||
public RegionManager(RegionDatabase store, Supplier<? extends ConcurrentRegionIndex> indexFactory, FlagRegistry flagRegistry) {
|
||||
public RegionManager(RegionDatabase store, Function<String, ? extends ConcurrentRegionIndex> indexFactory, FlagRegistry flagRegistry) {
|
||||
checkNotNull(store);
|
||||
checkNotNull(indexFactory);
|
||||
checkNotNull(flagRegistry, "flagRegistry");
|
||||
|
||||
this.store = store;
|
||||
this.indexFactory = indexFactory;
|
||||
this.index = indexFactory.get();
|
||||
this.index = indexFactory.apply(store.getName());
|
||||
this.flagRegistry = flagRegistry;
|
||||
}
|
||||
|
||||
@ -218,7 +217,7 @@ public void setRegions(Map<String, ProtectedRegion> regions) {
|
||||
public void setRegions(Collection<ProtectedRegion> regions) {
|
||||
checkNotNull(regions);
|
||||
|
||||
ConcurrentRegionIndex newIndex = indexFactory.get();
|
||||
ConcurrentRegionIndex newIndex = indexFactory.apply(getName());
|
||||
newIndex.addAll(regions);
|
||||
newIndex.getAndClearDifference(); // Clear changes
|
||||
this.index = newIndex;
|
||||
|
@ -41,8 +41,8 @@
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
*/
|
||||
public class ChunkHashTable implements ConcurrentRegionIndex {
|
||||
|
||||
private final String name;
|
||||
private ListeningExecutorService executor = createExecutor();
|
||||
private LongHashTable<ChunkState> states = new LongHashTable<>();
|
||||
private final RegionIndex index;
|
||||
@ -63,10 +64,12 @@ public class ChunkHashTable implements ConcurrentRegionIndex {
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param index the index
|
||||
* @param name
|
||||
*/
|
||||
public ChunkHashTable(RegionIndex index) {
|
||||
public ChunkHashTable(RegionIndex index, String name) {
|
||||
checkNotNull(index);
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,8 +78,8 @@ public ChunkHashTable(RegionIndex index) {
|
||||
* @return an executor service
|
||||
*/
|
||||
private ListeningExecutorService createExecutor() {
|
||||
return MoreExecutors.listeningDecorator(
|
||||
EvenMoreExecutors.newBoundedCachedThreadPool(0, 4, Integer.MAX_VALUE));
|
||||
return MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 4, Integer.MAX_VALUE,
|
||||
"WorldGuard Region Chunk Table - " + name));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -361,17 +364,17 @@ public boolean isLoaded() {
|
||||
/**
|
||||
* A factory for instances of {@code ChunkHashCache}.
|
||||
*/
|
||||
public static class Factory implements Supplier<ChunkHashTable> {
|
||||
private final Supplier<? extends ConcurrentRegionIndex> supplier;
|
||||
public static class Factory implements Function<String, ChunkHashTable> {
|
||||
private final Function<String, ? extends ConcurrentRegionIndex> supplier;
|
||||
|
||||
public Factory(Supplier<? extends ConcurrentRegionIndex> supplier) {
|
||||
public Factory(Function<String, ? extends ConcurrentRegionIndex> supplier) {
|
||||
checkNotNull(supplier);
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkHashTable get() {
|
||||
return new ChunkHashTable(supplier.get());
|
||||
public ChunkHashTable apply(String name) {
|
||||
return new ChunkHashTable(supplier.apply(name), name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
import com.sk89q.worldguard.protection.managers.RemovalStrategy;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@ -35,10 +36,8 @@
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An index that stores regions in a hash map, which allows for fast lookup
|
||||
@ -287,9 +286,9 @@ public void setDirty(boolean dirty) {
|
||||
/**
|
||||
* A factory for new instances using this index.
|
||||
*/
|
||||
public static final class Factory implements Supplier<HashMapIndex> {
|
||||
public static final class Factory implements Function<String, HashMapIndex> {
|
||||
@Override
|
||||
public HashMapIndex get() {
|
||||
public HashMapIndex apply(String name) {
|
||||
return new HashMapIndex();
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,8 @@
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* An implementation of an index that uses {@link HashMapIndex} for queries
|
||||
@ -103,9 +103,9 @@ public void applyIntersecting(ProtectedRegion region, Predicate<ProtectedRegion>
|
||||
/**
|
||||
* A factory for new instances using this index.
|
||||
*/
|
||||
public static final class Factory implements Supplier<PriorityRTreeIndex> {
|
||||
public static final class Factory implements Function<String, PriorityRTreeIndex> {
|
||||
@Override
|
||||
public PriorityRTreeIndex get() {
|
||||
public PriorityRTreeIndex apply(String name) {
|
||||
return new PriorityRTreeIndex();
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,12 @@
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
@ -47,7 +52,7 @@ public class UUIDMigration extends AbstractMigration {
|
||||
private static final Logger log = Logger.getLogger(UUIDMigration.class.getCanonicalName());
|
||||
private static final int LOG_DELAY = 5000;
|
||||
|
||||
private final Timer timer = new Timer();
|
||||
private final Timer timer = new Timer("WorldGuard UUID Migration");
|
||||
private final ProfileService profileService;
|
||||
private final FlagRegistry flagRegistry;
|
||||
private final ConcurrentMap<String, UUID> resolvedNames = new ConcurrentHashMap<>();
|
||||
|
@ -41,7 +41,6 @@
|
||||
import com.sk89q.worldguard.session.handler.WaterBreathing;
|
||||
import com.sk89q.worldguard.session.handler.WeatherLockFlag;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Arrays;
|
||||
@ -61,25 +60,18 @@ public abstract class AbstractSessionManager implements SessionManager {
|
||||
private final LoadingCache<WorldPlayerTuple, Boolean> bypassCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(1000)
|
||||
.expireAfterAccess(2, TimeUnit.SECONDS)
|
||||
.build(new CacheLoader<WorldPlayerTuple, Boolean>() {
|
||||
@Override
|
||||
public Boolean load(@Nonnull WorldPlayerTuple tuple) throws Exception {
|
||||
return tuple.getPlayer().hasPermission("worldguard.region.bypass." + tuple.getWorld().getName());
|
||||
}
|
||||
});
|
||||
.build(CacheLoader.from(tuple ->
|
||||
tuple.getPlayer().hasPermission("worldguard.region.bypass." + tuple.getWorld().getName())));
|
||||
|
||||
private final LoadingCache<CacheKey, Session> sessions = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(SESSION_LIFETIME, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<CacheKey, Session>() {
|
||||
@Override
|
||||
public Session load(@Nonnull CacheKey key) throws Exception {
|
||||
return createSession(key.playerRef.get());
|
||||
}
|
||||
});
|
||||
.build(CacheLoader.from(key ->
|
||||
createSession(key.playerRef.get())));
|
||||
|
||||
private List<Handler.Factory<? extends Handler>> handlers = new LinkedList<>();
|
||||
|
||||
private static final List<Handler.Factory<? extends Handler>> defaultHandlers = new LinkedList<>();
|
||||
|
||||
static {
|
||||
Handler.Factory<?>[] factories = {
|
||||
HealFlag.FACTORY,
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldguard.util.concurrent;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
@ -43,11 +45,28 @@ private EvenMoreExecutors() {
|
||||
* @return the newly created thread pool
|
||||
*/
|
||||
public static ExecutorService newBoundedCachedThreadPool(int minThreads, int maxThreads, int queueSize) {
|
||||
return newBoundedCachedThreadPool(minThreads, maxThreads, queueSize, null);}
|
||||
|
||||
/**
|
||||
* Creates a thread pool that creates new threads as needed up to
|
||||
* a maximum number of threads, but will reuse previously constructed
|
||||
* threads when they are available.
|
||||
*
|
||||
* @param minThreads the minimum number of threads to have at a given time
|
||||
* @param maxThreads the maximum number of threads to have at a given time
|
||||
* @param queueSize the size of the queue before new submissions are rejected
|
||||
* @param threadFormat thread name formatter
|
||||
* @return the newly created thread pool
|
||||
*/
|
||||
public static ExecutorService newBoundedCachedThreadPool(int minThreads, int maxThreads, int queueSize, String threadFormat) {
|
||||
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
|
||||
minThreads, maxThreads,
|
||||
60L, TimeUnit.SECONDS,
|
||||
new LinkedBlockingDeque<>(queueSize));
|
||||
threadPoolExecutor.allowCoreThreadTimeOut(true);
|
||||
if (threadFormat != null) {
|
||||
threadPoolExecutor.setThreadFactory(new ThreadFactoryBuilder().setNameFormat(threadFormat).build());
|
||||
}
|
||||
return threadPoolExecutor;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user