diff --git a/src/main/java/github/kasuminova/mmce/common/concurrent/Locks.java b/src/main/java/github/kasuminova/mmce/common/concurrent/Locks.java deleted file mode 100644 index 178aa353..00000000 --- a/src/main/java/github/kasuminova/mmce/common/concurrent/Locks.java +++ /dev/null @@ -1,11 +0,0 @@ -package github.kasuminova.mmce.common.concurrent; - -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -public class Locks { - /** - * 更新锁,用来进行方块更新、同步等非线程安全操作。 - */ - public static final Lock UPDATE_LOCK = new ReentrantLock(); -} diff --git a/src/main/java/github/kasuminova/mmce/common/concurrent/Sync.java b/src/main/java/github/kasuminova/mmce/common/concurrent/Sync.java new file mode 100644 index 00000000..51056318 --- /dev/null +++ b/src/main/java/github/kasuminova/mmce/common/concurrent/Sync.java @@ -0,0 +1,12 @@ +package github.kasuminova.mmce.common.concurrent; + +public class Sync { + /** + *

全局同步方法,用来进行方块更新、同步等非线程安全操作。

+ *

Global synchronization method.

+ *

For non-thread-safe operations such as block update and synchronization.

+ */ + public static synchronized void doSyncAction(Action action) { + action.doAction(); + } +} diff --git a/src/main/java/hellfirepvp/modularmachinery/common/crafting/helper/RecipeCraftingContext.java b/src/main/java/hellfirepvp/modularmachinery/common/crafting/helper/RecipeCraftingContext.java index dc3efea8..f9f46e01 100644 --- a/src/main/java/hellfirepvp/modularmachinery/common/crafting/helper/RecipeCraftingContext.java +++ b/src/main/java/hellfirepvp/modularmachinery/common/crafting/helper/RecipeCraftingContext.java @@ -10,7 +10,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; -import github.kasuminova.mmce.common.concurrent.Locks; +import github.kasuminova.mmce.common.concurrent.Sync; import hellfirepvp.modularmachinery.common.crafting.ActiveMachineRecipe; import hellfirepvp.modularmachinery.common.crafting.MachineRecipe; import hellfirepvp.modularmachinery.common.crafting.command.ControllerCommandSender; @@ -27,6 +27,8 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -122,15 +124,13 @@ public CraftingCheckResult ioTick(int currentTick) { perTickRequirement.startIOTick(this, durMultiplier); for (ProcessingComponent component : getComponentsFor(requirement, requirement.tag)) { - CraftCheck result; + AtomicReference result = new AtomicReference<>(); if (perTickRequirement instanceof Asyncable) { - result = perTickRequirement.doIOTick(component, this); + result.set(perTickRequirement.doIOTick(component, this)); } else { - Locks.UPDATE_LOCK.lock(); - result = perTickRequirement.doIOTick(component, this); - Locks.UPDATE_LOCK.unlock(); + Sync.doSyncAction(() -> result.set(perTickRequirement.doIOTick(component, this))); } - if (result.isSuccess()) { + if (result.get().isSuccess()) { break; } } @@ -182,15 +182,13 @@ public void startCrafting(long seed) { requirement.startRequirementCheck(chance, this); for (ProcessingComponent component : getComponentsFor(requirement, requirement.tag)) { - boolean success; + AtomicBoolean success = new AtomicBoolean(false); if (requirement instanceof Asyncable) { - success = requirement.startCrafting(component, this, chance); + success.set(requirement.startCrafting(component, this, chance)); } else { - Locks.UPDATE_LOCK.lock(); - success = requirement.startCrafting(component, this, chance); - Locks.UPDATE_LOCK.unlock(); + Sync.doSyncAction(() -> success.set(requirement.startCrafting(component, this, chance))); } - if (success) { + if (success.get()) { requirement.endRequirementCheck(); break; } @@ -211,15 +209,13 @@ public void finishCrafting(long seed) { requirement.startRequirementCheck(chance, this); for (ProcessingComponent component : getComponentsFor(requirement, requirement.tag)) { - CraftCheck check; + AtomicReference check = new AtomicReference<>(); if (requirement instanceof Asyncable) { - check = requirement.finishCrafting(component, this, chance); + check.set(requirement.finishCrafting(component, this, chance)); } else { - Locks.UPDATE_LOCK.lock(); - check = requirement.finishCrafting(component, this, chance); - Locks.UPDATE_LOCK.unlock(); + Sync.doSyncAction(() -> check.set(requirement.finishCrafting(component, this, chance))); } - if (check.isSuccess()) { + if (check.get().isSuccess()) { requirement.endRequirementCheck(); break; } diff --git a/src/main/java/hellfirepvp/modularmachinery/common/tiles/TileMachineController.java b/src/main/java/hellfirepvp/modularmachinery/common/tiles/TileMachineController.java index e34cb695..325d817a 100644 --- a/src/main/java/hellfirepvp/modularmachinery/common/tiles/TileMachineController.java +++ b/src/main/java/hellfirepvp/modularmachinery/common/tiles/TileMachineController.java @@ -14,7 +14,7 @@ import crafttweaker.api.world.IBlockPos; import crafttweaker.api.world.IWorld; import crafttweaker.util.IEventHandler; -import github.kasuminova.mmce.common.concurrent.Locks; +import github.kasuminova.mmce.common.concurrent.Sync; import github.kasuminova.mmce.common.concurrent.TaskExecutor; import hellfirepvp.modularmachinery.ModularMachinery; import hellfirepvp.modularmachinery.common.block.BlockController; @@ -346,10 +346,10 @@ private void tryStartRecipe(@Nonnull ActiveMachineRecipe activeRecipe, @Nullable RecipeCraftingContext.CraftingCheckResult tryResult = onCheck(finalContext); if (tryResult.isSuccess()) { - Locks.UPDATE_LOCK.lock(); - onStart(activeRecipe, finalContext); - markForUpdate(); - Locks.UPDATE_LOCK.unlock(); + Sync.doSyncAction(() -> { + onStart(activeRecipe, finalContext); + markForUpdate(); + }); } else { this.craftingStatus = CraftingStatus.failure(tryResult.getFirstErrorMessage("")); this.activeRecipe = null; diff --git a/src/main/java/hellfirepvp/modularmachinery/common/tiles/base/TileEnergyHatch.java b/src/main/java/hellfirepvp/modularmachinery/common/tiles/base/TileEnergyHatch.java index 00d0d2a7..3b1af21f 100644 --- a/src/main/java/hellfirepvp/modularmachinery/common/tiles/base/TileEnergyHatch.java +++ b/src/main/java/hellfirepvp/modularmachinery/common/tiles/base/TileEnergyHatch.java @@ -10,7 +10,7 @@ import com.brandon3055.draconicevolution.DEFeatures; import com.brandon3055.draconicevolution.blocks.tileentity.TileEnergyStorageCore; -import github.kasuminova.mmce.common.concurrent.Locks; +import github.kasuminova.mmce.common.concurrent.Sync; import gregtech.api.capability.GregtechCapabilities; import hellfirepvp.modularmachinery.common.base.Mods; import hellfirepvp.modularmachinery.common.block.prop.EnergyHatchData; @@ -31,6 +31,8 @@ import javax.annotation.Nullable; +import java.util.concurrent.atomic.AtomicBoolean; + import static hellfirepvp.modularmachinery.common.block.prop.EnergyHatchData.*; /** @@ -209,30 +211,30 @@ public void setCurrentEnergy(long energy) { @Override public boolean extractEnergy(long extract) { - Locks.UPDATE_LOCK.lock(); - if (this.energy >= extract) { - this.energy -= extract; + AtomicBoolean atomicBoolean = new AtomicBoolean(false); + Sync.doSyncAction(() -> { + if (this.energy >= extract) { + this.energy -= extract; - markForUpdate(); - Locks.UPDATE_LOCK.unlock(); - return true; - } - Locks.UPDATE_LOCK.unlock(); - return false; + markForUpdate(); + atomicBoolean.set(true); + } + }); + return atomicBoolean.get(); } @Override public boolean receiveEnergy(long receive) { - Locks.UPDATE_LOCK.lock(); - if (getRemainingCapacity() >= receive) { - this.energy += receive; + AtomicBoolean atomicBoolean = new AtomicBoolean(false); + Sync.doSyncAction(() -> { + if (getRemainingCapacity() >= receive) { + this.energy += receive; - markForUpdate(); - Locks.UPDATE_LOCK.unlock(); - return true; - } - Locks.UPDATE_LOCK.unlock(); - return false; + markForUpdate(); + atomicBoolean.set(true); + } + }); + return atomicBoolean.get(); } @Override diff --git a/src/main/java/hellfirepvp/modularmachinery/common/tiles/base/TileEntitySynchronized.java b/src/main/java/hellfirepvp/modularmachinery/common/tiles/base/TileEntitySynchronized.java index 236c2375..542aaf4a 100644 --- a/src/main/java/hellfirepvp/modularmachinery/common/tiles/base/TileEntitySynchronized.java +++ b/src/main/java/hellfirepvp/modularmachinery/common/tiles/base/TileEntitySynchronized.java @@ -8,7 +8,7 @@ package hellfirepvp.modularmachinery.common.tiles.base; -import github.kasuminova.mmce.common.concurrent.Locks; +import github.kasuminova.mmce.common.concurrent.Sync; import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; @@ -81,9 +81,7 @@ public void markForUpdate() { } public void markForUpdateSync() { - Locks.UPDATE_LOCK.lock(); - markForUpdate(); - Locks.UPDATE_LOCK.unlock(); + Sync.doSyncAction(this::markForUpdate); } } diff --git a/src/main/java/hellfirepvp/modularmachinery/common/util/IOInventory.java b/src/main/java/hellfirepvp/modularmachinery/common/util/IOInventory.java index 38c5e470..a33a8ac0 100644 --- a/src/main/java/hellfirepvp/modularmachinery/common/util/IOInventory.java +++ b/src/main/java/hellfirepvp/modularmachinery/common/util/IOInventory.java @@ -8,7 +8,7 @@ package hellfirepvp.modularmachinery.common.util; -import github.kasuminova.mmce.common.concurrent.Locks; +import github.kasuminova.mmce.common.concurrent.Sync; import hellfirepvp.modularmachinery.common.tiles.base.TileEntitySynchronized; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -20,6 +20,7 @@ import javax.annotation.Nonnull; import java.util.*; +import java.util.concurrent.atomic.AtomicReference; /** * This class is part of the Modular Machinery Mod @@ -129,15 +130,15 @@ public IItemHandlerModifiable asGUIAccess() { @Override public void setStackInSlot(int slot, @Nonnull ItemStack stack) { - Locks.UPDATE_LOCK.lock(); - if (this.inventory.containsKey(slot)) { - this.inventory.get(slot).itemStack = stack; - owner.markForUpdate(); - if (listener != null) { - listener.onChange(); + Sync.doSyncAction(() -> { + if (this.inventory.containsKey(slot)) { + this.inventory.get(slot).itemStack = stack; + owner.markForUpdate(); + if (listener != null) { + listener.onChange(); + } } - } - Locks.UPDATE_LOCK.unlock(); + }); } @Override @@ -163,15 +164,19 @@ public ItemStack getStackInSlot(int slot) { @Nonnull public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { if (stack.isEmpty()) return stack; - Locks.UPDATE_LOCK.lock(); + + AtomicReference stackRef = new AtomicReference<>(stack); + Sync.doSyncAction(() -> stackRef.set(insertItemInternal(slot, stack, simulate))); + return stackRef.get(); + } + + private ItemStack insertItemInternal(int slot, @Nonnull ItemStack stack, boolean simulate) { if (!allowAnySlots) { if (!arrayContains(inSlots, slot)) { - Locks.UPDATE_LOCK.unlock(); return stack; } } if (!this.inventory.containsKey(slot)) { - Locks.UPDATE_LOCK.unlock(); return stack; //Shouldn't happen anymore here tho } @@ -181,7 +186,6 @@ public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate ItemStack existing = copyWithSize(holder.itemStack, holder.itemStack.getCount()); int max = Math.min(existing.getMaxStackSize(), getSlotLimit(slot)); if (existing.getCount() >= max || !canMergeItemStacks(existing, toInsert)) { - Locks.UPDATE_LOCK.unlock(); return stack; } int movable = Math.min(max - existing.getCount(), stack.getCount()); @@ -193,12 +197,10 @@ public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate } } if (movable >= stack.getCount()) { - Locks.UPDATE_LOCK.unlock(); return ItemStack.EMPTY; } else { ItemStack copy = stack.copy(); copy.shrink(movable); - Locks.UPDATE_LOCK.unlock(); return copy; } } else { @@ -211,7 +213,6 @@ public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate listener.onChange(); } } - Locks.UPDATE_LOCK.unlock(); return ItemStack.EMPTY; } else { ItemStack copy = stack.copy(); @@ -225,7 +226,6 @@ public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate } copy = stack.copy(); copy.shrink(max); - Locks.UPDATE_LOCK.unlock(); return copy; } } @@ -234,26 +234,27 @@ public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate @Override @Nonnull public ItemStack extractItem(int slot, int amount, boolean simulate) { - Locks.UPDATE_LOCK.lock(); + AtomicReference stackRef = new AtomicReference<>(ItemStack.EMPTY); + Sync.doSyncAction(() -> stackRef.set(extractItemInternal(slot, amount, simulate))); + return stackRef.get(); + } + + private ItemStack extractItemInternal(int slot, int amount, boolean simulate) { if (!allowAnySlots) { if (!arrayContains(outSlots, slot)) { - Locks.UPDATE_LOCK.unlock(); return ItemStack.EMPTY; } } if (!this.inventory.containsKey(slot)) { - Locks.UPDATE_LOCK.unlock(); return ItemStack.EMPTY; //Shouldn't happen anymore here tho } SlotStackHolder holder = this.inventory.get(slot); if (holder.itemStack.isEmpty()) { - Locks.UPDATE_LOCK.unlock(); return ItemStack.EMPTY; } ItemStack extract = copyWithSize(holder.itemStack, Math.min(amount, holder.itemStack.getCount())); if (extract.isEmpty()) { - Locks.UPDATE_LOCK.unlock(); return ItemStack.EMPTY; } if (!simulate) { @@ -263,7 +264,6 @@ public ItemStack extractItem(int slot, int amount, boolean simulate) { } } owner.markForUpdate(); - Locks.UPDATE_LOCK.unlock(); return extract; }