Java实现延迟执行功能工具类CallLaterUtil
在项目中经常遇到某些功能需要10秒后执行,1分钟后执行等延迟执行的任务
本例中使用多线程队列去消费需要延迟执行的任务
使用方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public static void main(String[] args) throws InterruptedException { IFunction<Object, TestCallLater> fun = new Function<Object, TestCallLater>(new TestCallLater()) { @Override public Object apply(Object[] argArray) { System.out.println(_parent +"--" + argArray[0] + argArray[1]); return null; } }; Object[] p = {1, "2"}; // 5秒后执行 CallLaterUtil.callLater(5, fun, p); Thread.sleep(10000); //5秒后执行 CallLaterUtil.callLater(5, fun, p); } |
实现类:
CallLaterUtil.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
package net.code2048.common.utils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import net.code2048.common.function.Handler; import net.code2048.common.function.IFunction; import net.code2048.common.theadQueue.QueueChannel; /** * 延时执行 * @author 破晓(www.code2048.net) * */ public class CallLaterUtil { private static CallLaterUtil manager = new CallLaterUtil(); /** * 添加延时执行任务 * @param time * @param fun * @param param */ public static void callLater(int time, IFunction<?, ?> fun, Object[] param) { manager.addTask(time, fun, param, null); } /** * 添加延时执行任务 * @param time * @param fun * @param param * @param key 任务标志 需要移除任务或获取任务信息时 可传入此参数 */ public static void callLater(int time, IFunction<?, ?> fun, Object[] param, String key) { manager.addTask(time, fun, param, key); } /** * 取消任务 * @param key */ public static void clearCallLater(String key) { manager.removeTask(key); } /** * 获取任务剩余时间 * @param key * @return */ public static int getTaskTimeout(String key) { Task task = manager.getTask(key); if(task != null) return task.time; return 0; } private Timer timer; private boolean running = false; private List<Task> tasks; private Map<String, Task> taskIndex = new HashMap<String, Task>(); private Handler<CallLaterUtil, Task> handler = new Handler<CallLaterUtil, CallLaterUtil.Task>() { @Override public void handler(Task task) { task.call(); } }; private QueueChannel<Task> channel = QueueChannel.build("CallLaterUtil", handler, 3); private CallLaterUtil() { timer = new Timer(); tasks = new ArrayList<Task>(); } public void addTask(int time, IFunction<?, ?> fun, Object[] param, String key) { Task task = new Task(time, fun, param, key); tasks.add(task); if(key != null) taskIndex.put(key, task); if(!running) startTimer(); } public boolean removeTask(String key) { if(taskIndex.containsKey(key)) { Task task = taskIndex.get(key); tasks.remove(task); taskIndex.remove(key); return true; } return false; } public Task getTask(String key) { if(taskIndex.containsKey(key)) return taskIndex.get(key); return null; } private void startTimer() { timer.scheduleAtFixedRate(new TimerTask() { public void run() { try{ Task item; for(int i=tasks.size()-1; i>=0; i--) { item = tasks.get(i); item.time--; if(item.time <= 0) { tasks.remove(i); if(item.key != null && taskIndex.containsKey(item.key)) taskIndex.remove(item.key); channel.offerLast(item); } } if(tasks.size() == 0) { taskIndex.clear(); this.cancel(); CallLaterUtil.manager.clearTimerTask(); } } catch(Exception e) { e.printStackTrace(); } } }, 100, 1000); running = true; } public void clearTimerTask() { timer.purge(); running = false; } class Task{ public Task(int t, IFunction<?, ?> back, Object[] p, String k) { time = t; callBack = back; param = p; this.key = k; } public String key; public int time = 0; public IFunction<?, ?> callBack; public Object[] param; public void call() { try{ if(callBack != null) callBack.apply(param); } catch(Exception e) { e.getStackTrace(); } } } } |
本工具类依赖多线程队列的工具类,具体代码请查看: