环境:
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();
}