基于ScheduledThreadPoolExecutor线程池的周期性任务、延时自定义封装

环境:

jdk1.8

初衷:

在最近开发的项目中经常要使用到延时任务、周期性任务和等待消息反馈并有10s超时的需求,所以基于线程池的功能进行了小小的封装,如对你有所帮助我很荣幸,如有问题还望指正,谢谢!

使用方式:

/**
 * @author:muge
 * @create: 2022-12-08 13:19
 * @Description:
 */
public class TimerTest {

    static ScheduledFuture<?> future1;
    static ScheduledFuture<?> future2;
    static ScheduledFuture<?> future3;

    public static void main(String[] args) {

        /**
         * 用于周期性执行
         */
        future1 = TimerGlobal.getInstance().enqueue(new FixedRateRunnable(1000, new FixedRateListener() {
            @Override
            public void fixedRate(int count) {
                //周期性执行

                //达到一定条件,直接结束
                if (count > 100) {
                    TimerGlobal.getInstance().remove(future1);
                }
            }
        }));


        /**
         * 用于等待反馈自定义消息,并且在10s未收到消息,会进行超时反馈
         */
        future2 = TimerGlobal.getInstance().enqueue(
                new TimeoutRunnable(new MessageListener() {
                    @Override
                    public void onMessage(Object obj) {
                        //反馈的消息
                    }
                }, new TimeoutListener() {
                    @Override
                    public void timeout() {
                        //10s未反馈消息的超时
                    }
                }));


        /**
         * 用于指定时长的延时任务
         */
        future3 = TimerGlobal.getInstance().enqueue(new TimeoutRunnable(10 * 1000, new TimeoutListener() {
            @Override
            public void timeout() {
                //延时执行


                //在延时到达前达到一定条件可以提前结束
                //TimerGlobal.getInstance().remove(future3);
            }
        }));
    }


}

核心代码:

TimerGlobal.java 核心方法,子线程的添加及删除
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Description 核心方法
 * @Author muge
 * @Date 08-05-2022
 */
public class TimerGlobal {

    private final String TAG = TimerGlobal.class.getSimpleName();

    private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50);

    private Map<ScheduledFuture<?>, Boolean> hashMap = new HashMap<>();

    private TimerGlobal() {
        this.init();
    }

    public static TimerGlobal getInstance() {
        return Holder.TIMER_GLOBAL;
    }

    private static class Holder {
        private static TimerGlobal TIMER_GLOBAL = new TimerGlobal();
    }

    /**
     * 初始化删除功能的周期性定时器
     */
    public void init() {
        TimerGlobal.getInstance().executor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                if (TimerGlobal.getInstance().hashMap.size() > 0) {
                    Iterator<Map.Entry<ScheduledFuture<?>, Boolean>> iterator = TimerGlobal.getInstance().hashMap.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry<ScheduledFuture<?>, Boolean> entry = iterator.next();
                        ScheduledFuture<?> future = entry.getKey();
                        boolean b = entry.getValue();
                        if (!b) {
                            future.cancel(true);//取消后,executor会自动变更 executor.getQueue().size()
                            iterator.remove();
                            future = null;//目前测试该置空无效,原因未知,后续研究
                            System.out.println("清除定时器,数量:" + TimerGlobal.getInstance().executor.getQueue().size());
                        }
                    }
                }
            }
        }, 100, 500, TimeUnit.MILLISECONDS);
    }

    /**
     * 添加周期性定时器,同时删除原有已存在的future
     * @param scheduledFuture
     * @param callback
     * @return
     */
    public ScheduledFuture<?> enqueue(ScheduledFuture<?> scheduledFuture, BaseTimerCallback callback) {
        if (scheduledFuture != null) {
            TimerGlobal.getInstance().remove(scheduledFuture);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return TimerGlobal.getInstance().enqueue(callback);
    }

    /**
     * 添加周期性定时器
     * @param callback
     * @return
     */
    public ScheduledFuture<?> enqueue(BaseTimerCallback callback) {
        if (callback == null) return null;
        ScheduledFuture<?> schedule = null;
        String classType = "";
        if (callback instanceof TimeoutCallback) {
            //指定延迟时间的一次任务,用于消息10s超时的回调
            classType = "TimeoutCallback";
            schedule = TimerGlobal.getInstance().executor.schedule(callback, callback.getPeriod(), TimeUnit.MILLISECONDS);
        } else if (callback instanceof FixedRateCallback) {
            //指定时间间隔的周期性任务
            classType = "FixedRateCallback";
            schedule = TimerGlobal.getInstance().executor.scheduleAtFixedRate(callback, 100, callback.getPeriod(), TimeUnit.MILLISECONDS);
        }
        TimerGlobal.getInstance().hashMap.put(schedule, true);
        System.out.println("添加定时器,类型:" + classType + " 总数:" + TimerGlobal.getInstance().executor.getQueue().size());
        return schedule;
    }

    /**
     * 删除定时器
     * @param future
     */
    public void remove(ScheduledFuture<?> future) {
        if (future != null) {
            if (TimerGlobal.getInstance().hashMap.containsKey(future)) {
                TimerGlobal.getInstance().hashMap.put(future, false);
            }
        }
    }
}
BaseTimerRunnable.java 基类

/**
 * @Description runnable子基类
 * @Author muge
 * @Date 09-27-2022
 */
public class BaseTimerRunnable implements Runnable{

    private int period;

    public int getPeriod() {
        return period;
    }

    public void setPeriod(int period) {
        this.period = period;
    }

    @Override
    public void run() {
    }
}
FixedRateRunnable.java 周期性任务Runnable

/**
 * @Description 周期性任务Runnable
 * @Author muge
 * @Date 08-05-2022
 */
public class FixedRateRunnable extends BaseTimerRunnable {

    /**
     * 统计一共运行了几次
     */
    private int count = 0;

    public int getCount() {
        return count;
    }

    /**
     * 固定时间频率监听
     */
    private FixedRateListener fixedRateListener;

    public FixedRateRunnable(int period, FixedRateListener fixedRateListener) {
        this.setPeriod(Math.max(period, 100));//固定频率 单位 毫秒 默认最低100毫秒
        this.fixedRateListener = fixedRateListener;
    }

    @Override
    public void run() {
        count++;
        fixedRateListener.fixedRate(count);
    }
}

   TimeoutRunnable.java  消息回调及超时和延时任务Runnable


/**
 * @Description
 * 消息回调及超时Runnable
 * 延时任务Runnable
 * @Author muge
 * @Date 08-05-2022
 */
public class TimeoutRunnable extends BaseTimerRunnable {

    /**
     * 消息反馈监听
     */
    private MessageListener messageListener;

    /**
     * 时间超时监听
     */
    private TimeoutListener timeoutListener;

    /**
     * 默认10s超时
     *
     * @param messageListener
     * @param timeoutListener
     */
    public TimeoutRunnable(MessageListener messageListener, TimeoutListener timeoutListener) {
        this.setPeriod(10 * 1000);//默认10s超时,也可增加参数period,通过传值指定超时时间
        this.messageListener = messageListener;
        this.timeoutListener = timeoutListener;
    }


    /**
     * 10延时
     *
     * @param period
     * @param timeoutListener
     */
    public TimeoutRunnable(int period, TimeoutListener timeoutListener) {
        this.setPeriod(period);
        this.timeoutListener = timeoutListener;
    }

    public MessageListener getMessageListener() {
        return messageListener;
    }

    @Override
    public void run() {
        timeoutListener.timeout();
    }
}

 接口类:

FixedRateListener.java MessageListener.java TimeoutListener.java
/**
 * @Description 固定时间频率的监听反馈
 * @Author muge
 * @Date 05-17-2022
 */
public interface FixedRateListener {

    void fixedRate(int count);
}




/**
 * @Description 自定义消息接收
 * @Author muge
 * @Date 05-19-2022
 */
public interface MessageListener {

    void onMessage(Object obj);
}



/**
 * @Description 超时监听
 * @Author muge
 * @Date 05-17-2022
 */
public interface TimeoutListener {

    void timeout();

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值