minglipro 09792e2c3b
All checks were successful
Gitea Actions Build / Build (push) Successful in 53s
no message
2025-09-10 20:58:17 +08:00

94 lines
2.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile Debouncer.java
* LastUpdate 2025-09-09 08:37:34
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.functions;
import java.util.concurrent.*;
/**
* 防抖器类,用于实现防抖功能,防止在短时间内重复执行相同任务
*
* @author MingLiPro
*/
public class Debouncer {
private final ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor();
private final ConcurrentHashMap<Object, Future<?>> delayedMap =
new ConcurrentHashMap<>();
private final long delay;
/**
* 构造函数,创建一个防抖器实例
*
* @param delay 延迟时间
* @param unit 时间单位
*/
public Debouncer(long delay, TimeUnit unit) {
this.delay = unit.toMillis(delay);
}
/**
* 执行防抖操作如果在指定延迟时间内再次调用相同key的任务则取消之前的任务并重新计时
*
* @param key 任务的唯一标识符,用于区分不同任务
* @param task 要执行的任务
*/
public void debounce(final Object key, final Runnable task) {
// 提交新任务并获取之前可能存在的任务
final Future<?> prev = delayedMap.put(
key,
scheduler.schedule(
() -> {
try {
task.run();
} finally {
// 任务执行完成后从映射中移除
delayedMap.remove(key);
}
},
delay,
TimeUnit.MILLISECONDS
)
);
// 如果之前存在任务,则取消它
if (prev != null) {
prev.cancel(true);
}
}
/**
* 关闭防抖器,取消所有待执行的任务并关闭调度器
*/
public void shutdown() {
// 先取消所有延迟任务
for (Future<?> future : delayedMap.values()) {
future.cancel(true);
}
delayedMap.clear();
// 再关闭调度器
scheduler.shutdownNow();
}
}