Java 防抖动函数的实现

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

概述

目前在开发一个文档监控类工具时遇到一个问题,希望在文档编写过程中不对文档做备份,而在文档编写结束时再备份,这就需要一个防抖函数。

防抖函数,就是指触发事件后在n 秒内函数只能执行一次,如果在n 秒内又触发了事件,则会重新计算函数执行时间。 简单的说,当一个动作连续触发,则只执行最后一次。

实现

我们可以使用ScheduledExecutorService的schedule方法实现,
为每个任务分配一个唯一的 key,使用ConcurrentHashMap来存储 key-future,使用future的 cancel 方法来取消线程任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
java复制代码package org.example.simple;

import java.util.concurrent.*;

/**
* @author Catch
* @since 2021-10-29
*/
public class Debounce {

private static final ScheduledExecutorService SCHEDULE = Executors.newSingleThreadScheduledExecutor();

// 使用 ConcurrentHashMap 来存储 Future
private static final ConcurrentHashMap<Object, Future<?>> DELAYED_MAP = new ConcurrentHashMap<>();

/**
* 抖动函数
*/
public static void debounce(final Object key, final Runnable runnable, long delay, TimeUnit unit) {
final Future<?> prev = DELAYED_MAP.put(key, SCHEDULE.schedule(() -> {
try {
runnable.run();
} finally {
// 如果任务运行完,则从 map 中移除
DELAYED_MAP.remove(key);
}
}, delay, unit));
// 如果任务还没运行,则取消任务
if (prev != null) {
prev.cancel(true);
}
}

/**
* 停止运行
*/
public static void shutdown() {
SCHEDULE.shutdownNow();
}

public static void main(String[] args) {
// 1,2 为每个任务的唯一 key
Debounce.debounce("1", () -> {System.out.println(11);}, 3, TimeUnit.SECONDS);
Debounce.debounce("1", () -> {System.out.println(22);}, 3, TimeUnit.SECONDS);
Debounce.debounce("1", () -> {System.out.println(33);}, 3, TimeUnit.SECONDS);
Debounce.debounce("2", () -> {System.out.println(44);}, 3, TimeUnit.SECONDS);
Debounce.debounce("2", () -> {System.out.println(44);}, 3, TimeUnit.SECONDS);
Debounce.debounce("2", () -> {System.out.println(44);}, 3, TimeUnit.SECONDS);
}

}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%