diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/InvocationDispatcher.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/InvocationDispatcher.java index 3bfa67a9e..a6cf8031b 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/InvocationDispatcher.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/InvocationDispatcher.java @@ -21,15 +21,14 @@ import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -/** - * When {@link #accept(T)} is called, this class invokes the handler on another thread. - * If {@link #accept(T)} is called more than one time before the handler starts processing, - * the handler will only be invoked once, taking the latest argument as its input. - * - * @author yushijinhun - */ +/// When [#accept(T)] is called, this class invokes the handler on another thread. +/// If [#accept(T)] is called more than one time before the handler starts processing, +/// the handler will only be invoked once, taking the latest argument as its input. +/// +/// @author yushijinhun public final class InvocationDispatcher implements Consumer { + /// @param executor The executor must dispatch all tasks to a single thread. public static InvocationDispatcher runOn(Executor executor, Consumer action) { return new InvocationDispatcher<>(executor, action); } @@ -47,9 +46,10 @@ public final class InvocationDispatcher implements Consumer { public void accept(T t) { if (pendingArg.getAndSet(new Holder<>(t)) == null) { executor.execute(() -> { - synchronized (InvocationDispatcher.this) { - action.accept(pendingArg.getAndSet(null).value); - } + // If the executor supports multiple underlying threads, + // we need to add synchronization, but for now we can omit it :) + // synchronized (InvocationDispatcher.this) + action.accept(pendingArg.getAndSet(null).value); }); } }