JAVA 操作防抖(非RxJava方案)

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");

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值