欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA 操作防抖(非RxJava方案)

程序员文章站 2022-05-14 13:27:30
...
JAVA 操作防抖,在手机网络状态变化时发生了重复调用,因此需要进行防抖。
本打算用RxJava方案的,发现没必要那么麻烦,就找了个现成的类修改了下,发现确实还比较好用,代码如下。
package com.xxx.xxx;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 操作防抖
 * @param <T> 参数类型
 */
public class Debouncer<T> {
    private final ScheduledExecutorService sched = Executors.newScheduledThreadPool(1);
    private final ConcurrentHashMap<T, TimerTask> delayedMap = new ConcurrentHashMap<T, TimerTask>();
    private final Callback<T> callback;
    private final int interval;

    public interface Callback<T> {
        void call(T param);
    }

    public Debouncer(Callback<T> c, int interval) {
        this.callback = c;
        this.interval = interval;
    }

    public void call(T param) {
        TimerTask task = new TimerTask(param);

        TimerTask prev;
        do {
            prev = delayedMap.putIfAbsent(param, task);
            if (prev == null)
                sched.schedule(task, interval, TimeUnit.MILLISECONDS);
        }
        while (prev != null && !prev.extend()); // Exit only if new task was added to map, or existing task was extended successfully
    }

    public void terminate() {
        sched.shutdownNow();
    }

    // The task that wakes up when the wait time elapses
    private class TimerTask implements Runnable {
        private final T param;
        private long dueTime;
        private final Object lock = new Object();

        public TimerTask(T param) {
            this.param = param;
            extend();
        }

        public boolean extend() {
            synchronized (lock) {
                if (dueTime < 0) // Task has been shutdown
                    return false;
                dueTime = System.currentTimeMillis() + interval;
                return true;
            }
        }

        public void run() {
            synchronized (lock) {
                long remaining = dueTime - System.currentTimeMillis();
                if (remaining > 0) { // Re-schedule task
                    sched.schedule(this, remaining, TimeUnit.MILLISECONDS);
                } else { // Mark as terminated and invoke callback
                    dueTime = -1;
                    try {
                        callback.call(param);
                    } finally {
                        delayedMap.remove(param);
                    }
                }
            }
        }
    }
}


调用:

    private Debouncer<String> debouncer = new Debouncer(new Debouncer.Callback<String>(){
        @Override
        public void call(String param) {
            System.out.println("call with param:" + param);
        }
    }, 500);

debouncer.call("参数A");

上一篇: 字节流例子

下一篇: 字节流