lannyf
lannyf

Reputation: 11025

in java the after timer.cancel(), got exctpion

Trying do some debouncing, the use case is that client may send multiple requests to server in short interval unnecessarily. The requests are all the same but response is different at the time of the server processing, so the last response is the one to use.

With following code if do not always create a new timer, after timer.cancel(), the timer.schedule() will crash with "Timer already cancelled.".

Can't the timer be reused?

Is there better way to do the debouncing without using timer?

private Timer debouncerTimer = new Timer();
synchronized void debounceRequest() {
       
        debouncerTimer.cancel();

        //debouncerTimer = new Timer(); //<== without this one it crashes with IllegalStateException("Timer already cancelled.")

        debouncerTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                
                doSendRequest();
            }
        }, 150);
    }

Upvotes: 0

Views: 55

Answers (1)

data03&#39;
data03&#39;

Reputation: 61

A facility for threads to schedule tasks for future execution in a background thread. Tasks may be scheduled for one-time execution, or for repeated execution at regular intervals.

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Timer.html

Here is an example using ScheduledExecutorService that could work:

private ScheduledExecutorService debouncer = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> scheduledRequest;

synchronized void debounceRequest() {
    if (scheduledRequest != null) {
        scheduledRequest.cancel(false);
    }
    scheduledRequest = debouncer.scheduleWithFixedDelay(this::doSendRequest, 0, 150, TimeUnit.MILLISECONDS);
}

private void doSendRequest() {
    //Send request stuff here
}

Upvotes: 1

Related Questions