Repository: apache/dubbo
File: dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/AbstractTimerTask.java (Java)

Code before:
import org.apache.dubbo.common.timer.Timeout;
import org.apache.dubbo.common.timer.TimerTask;
import org.apache.dubbo.remoting.Channel;

import java.util.Collection;
import java.util.concurrent.TimeUnit;

public abstract class AbstractTimerTask implements TimerTask {

    private final ChannelProvider channelProvider;
    private final HashedWheelTimer hashedWheelTimer;

    private final Long tick;

    protected volatile boolean cancel = false;

    private volatile Timeout timeout;

    AbstractTimerTask(ChannelProvider channelProvider, HashedWheelTimer hashedWheelTimer, Long tick) {
        if (channelProvider == null || hashedWheelTimer == null || tick == null) {
            throw new IllegalArgumentException();
        }
        this.channelProvider = channelProvider;
        this.hashedWheelTimer = hashedWheelTimer;
        this.tick = tick;
        start();
    }

    static Long lastRead(Channel channel) {
        return (Long) channel.getAttribute(HeartbeatHandler.KEY_READ_TIMESTAMP);
    }

    static Long lastWrite(Channel channel) {
        return (Long) channel.getAttribute(HeartbeatHandler.KEY_WRITE_TIMESTAMP);
    }

    static Long now() {
        return System.currentTimeMillis();
    }

    private void start() {
        this.timeout = hashedWheelTimer.newTimeout(this, tick, TimeUnit.MILLISECONDS);
    }

    public synchronized void cancel() {
        this.cancel = true;
        this.timeout.cancel();
    }

    private synchronized void reput(Timeout timeout) {
        if (timeout == null) {

Review comment (suggestion):
The word 'inheritor' should be 'subclass' or 'subclasses' for better clarity and standard terminology.
```suggestion
        // do not start here because subclass should set additional timeout parameters before doing task.
```

Code after:
import org.apache.dubbo.common.timer.Timeout;
import org.apache.dubbo.common.timer.TimerTask;
import org.apache.dubbo.remoting.Channel;

import java.util.Collection;
import java.util.concurrent.TimeUnit;

public abstract class AbstractTimerTask implements TimerTask {

    private final ChannelProvider channelProvider;
    private final HashedWheelTimer hashedWheelTimer;

    private final Long tick;

    protected volatile boolean cancel = false;

    private volatile Timeout timeout;

    AbstractTimerTask(ChannelProvider channelProvider, HashedWheelTimer hashedWheelTimer, Long tick) {
        if (channelProvider == null || hashedWheelTimer == null || tick == null) {
            throw new IllegalArgumentException();
        }
        this.channelProvider = channelProvider;
        this.hashedWheelTimer = hashedWheelTimer;
        this.tick = tick;
        // do not start here because inheritor should set additional timeout parameters before doing task.
    }

    static Long lastRead(Channel channel) {
        return (Long) channel.getAttribute(HeartbeatHandler.KEY_READ_TIMESTAMP);
    }

    static Long lastWrite(Channel channel) {
        return (Long) channel.getAttribute(HeartbeatHandler.KEY_WRITE_TIMESTAMP);
    }

    static Long now() {
        return System.currentTimeMillis();
    }

    protected void start() {
        this.timeout = hashedWheelTimer.newTimeout(this, tick, TimeUnit.MILLISECONDS);
    }

    public synchronized void cancel() {
        this.cancel = true;
        this.timeout.cancel();
    }

    private synchronized void reput(Timeout timeout) {
        if (timeout == null) {