String keyString = key.toString(); CallTrack prev = synchronizationMap .get(keyString); CallTrack track = calculateNextCallTrack(prev, Instant. now()); synchronizationMap .put(keyString, track); taskScheduler .schedule( () -> { if (!track.equals(synchronizationMap .get(keyString))) { return; } runnable.run(); }, track.scheduledAt()); } @VisibleForTesting static CallTrack calculateNextCallTrack (@Nullable CallTrack prev, Instant now) { if (prev == null) { return new CallTrack(now, DEFAULT_MINIMUM_DELAY); } Duration observedInterval = Duration. between(prev.time(), now); Duration delay = min(max(prev.delay(), observedInterval), MAX_DELAY); return new CallTrack(now, delay); } public record CallTrack(Instant time, Duration delay) implements Serializable { Instant scheduledAt () { return time.plus(delay); } } 全体のコード量 全体でも30行以下。 言葉で説明するより コードのほうがシンプ ルでしょ? でも理解するの難しい よね><