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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
package com.yanzuoguang.util.thread;
import com.yanzuoguang.util.helper.Event;
import com.yanzuoguang.util.exception.ExceptionHelper;
import com.yanzuoguang.util.helper.StringHelper;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 自动执行任务
*
* @author 颜佐光
*/
public class RunPlan {
/**
* 任务锁
*/
private Object lock = new Object();
/**
* 任务队列
*/
private List<RunPlanData> list = new ArrayList<>();
/**
* 增加时触发的事件队列
*/
private Event<Runnable> onAdd = new Event<>();
/**
* 增加时触发的事件队列
*/
private Event<Runnable> onRemove = new Event<>();
/**
* 单项成功执行时的事件队列
*/
private Event<Runnable> onItemExecuted = new Event<>();
/**
* 全部执行完时触发的事件队列
*/
private Event<Runnable> onExecuted = new Event<>();
/**
* 增加时触发的事件队列
*
* @return 事件队列
*/
public Event<Runnable> getOnAdd() {
return onAdd;
}
/**
* 增加时触发的事件队列
*
* @return 事件队列
*/
public Event<Runnable> getOnRemove() {
return onRemove;
}
/**
* 单项成功执行时的事件队列
*
* @return 事件队列
*/
public Event<Runnable> getOnItemExecuted() {
return onItemExecuted;
}
/**
* 全部执行完时触发的事件队列
*
* @return 事件队列
*/
public Event<Runnable> getOnExecuted() {
return onExecuted;
}
/**
* 执行完任务后,是否需要删除该任务,并且设置允许执行的最大错误
*
* @param isRemove 执行完成是否删除
* @param maxError 最大错误次数
*/
public final void run(boolean isRemove, int maxError) {
for (int i = list.size() - 1; i >= 0; i--) {
long now = System.currentTimeMillis();
RunPlanData item;
synchronized (this.lock) {
item = list.size() > i ? list.get(i) : null;
}
if (item == null) {
continue;
}
double millSeconds = 0;
// 在Window CE中时间相减可能会出错
try {
// 处理非法改动时间
if (item.getDate() > now) {
item.setDate(now);
}
millSeconds = (now - item.getDate());
} catch (Exception ex) {
ExceptionHelper.handleException(ThreadHelper.class, ex);
}
// 未到执行时间
if (millSeconds <= item.getTime()) {
continue;
}
if (maxError == -1 || item.getExecuteError() < maxError) {
try {
item.addCount();
item.getExecute().run();
item.initError();
this.triggerEvent(this.onItemExecuted);
} catch (Exception ex) {
ExceptionHelper.handleException(RunPlan.class, ex);
}
item.initDate();
}
try {
if (isRemove) {
synchronized (this.lock) {
this.list.remove(i);
this.triggerEvent(this.onRemove);
}
}
} catch (Exception ex) {
ExceptionHelper.handleException(RunPlan.class, ex);
}
}
this.triggerEvent(this.onExecuted);
}
/**
* 设置需要执行的任务
*
* @param run 需要执行的程序
* @param vTime 间隔时间
* @return 执行标志
*/
public final String set(Runnable run, int vTime) {
// 创建临时任务数据
RunPlanData temp = new RunPlanData();
temp.setFlag(StringHelper.getNewID());
temp.setExecute(run);
temp.setTime(vTime);
synchronized (lock) {
list.add(temp);
}
this.triggerEvent(this.onAdd);
return temp.getFlag();
}
/**
* 清除需要执行的任务
*
* @param flag 执行标志
*/
public final void remove(String flag) {
synchronized (lock) {
for (RunPlanData item : this.list) {
if (item.getFlag().equals(flag)) {
this.list.remove(item);
this.triggerEvent(this.onRemove);
break;
}
}
}
}
/**
* 清除需要执行的任务
*
* @param run 执行的方法,注意有多个同样的方法时,只会清除第一个
*/
public final void remove(Runnable run) {
synchronized (lock) {
for (RunPlanData item : this.list) {
if (item.getExecute().equals(run)) {
this.list.remove(item);
this.triggerEvent(this.onRemove);
break;
}
}
}
}
/**
* 触发事件
*
* @param run 需要触发的事件队列
*/
private void triggerEvent(Event<Runnable> run) {
try {
if (run != null) {
run.exeucte(new RunExecute());
}
} catch (Exception ex) {
ExceptionHelper.handleException(ThreadHelper.class, ex);
}
}
/**
* 获取需要执行的任务长度
*
* @return 长度信息
*/
public final int getCount() {
return this.list.size();
}
}