如何为方法执行计数保护创建定时看门狗

How to create a timing watchdog for method execution count protection

我想编写一些代码,如果方法调用的计数在指定的时间间隔内超过了最大值,它会通知侦听器。

假设我想知道在滑动 30 秒的时间内调用方法是否有点太快。

在这种方法中,我会通知此 watchdog 它必须递增计数器。

而且我希望能够在配置的时间内跟踪超过 100 个呼叫。

所以看门狗将像这样实例化:new Watchdog(100, 30, TimeUnit.SECONDS, theListener);

如果遇到这种情况,我真的不知道如何开始编码。任何提示将不胜感激。

如果我已经很好地理解了,您需要一个或多个 WatchDog 来跟踪是否在 timeLapse 内达到了 maximumNumber?

我想这很适合观察者模式,其中一个主题(例如一个程序)向观察者发送通知(例如一个观察程序行为的看门狗)。

这里是 Watchdogs 正在观察的程序或主题:

public class Subject {
    private List<WatchDog> watchDogs = new ArrayList<>();

    public void add(WatchDog watchDog) {
        watchDogs.add(watchDog);
    }

    public void execute() {
        for (WatchDog watchDog : watchDogs) {
            watchDog.update();
        }
    }
}

看门狗定义如下:

// Verifies that maxCalls is not reached between lastTimeUpdateWasCalled and
// lastTimeUpdateWasCalled + periodInSeconds
public class WatchDog {
    private Date lastTimeUpdateWasCalled = null;
    private int currentNumberOfCalls = 0;

    private int maxCalls;
    private int periodInSeconds;

    public WatchDog(int maxCalls, int periodInSeconds) {
        this.maxCalls = maxCalls;
        this.periodInSeconds = periodInSeconds;
    }

    public void update() {
        this.currentNumberOfCalls = this.currentNumberOfCalls + 1;
        Date now = new Date();

        if (lastTimeUpdateWasCalled == null) {
            this.lastTimeUpdateWasCalled = now;
            this.currentNumberOfCalls = 1;
            return;
        }

        long endOfPeriodMillis = lastTimeUpdateWasCalled.getTime() + this.periodInSeconds * 1000L;
        Date endOfPeriod = new Date(endOfPeriodMillis);

        if (now.before(endOfPeriod)) {
            this.currentNumberOfCalls = this.currentNumberOfCalls + 1;
            if (this.currentNumberOfCalls >= this.maxCalls) {
                System.out.println("Watchdog has detected that " + this.currentNumberOfCalls + " have been done within "
                        + this.periodInSeconds + " seconds");
            }
        } else {
            // reinitialization
            this.currentNumberOfCalls = 1;
            this.lastTimeUpdateWasCalled = now;
        }

    }
}

以下是如何将所有内容组合在一起的方法:

public class Main {

    public static void main(String[] args) throws Exception {
        Subject s1 = new Subject();
        WatchDog w = new WatchDog(2, 2);
        s1.add(w);
        s1.execute();

        //Thread.sleep(2000);
        s1.execute();
    }
}

这里有更多关于观察者模式的信息:https://sourcemaking.com/design_patterns/observer