优化升级,支持任务执行计划的变更
This commit is contained in:
parent
b4603fa8f9
commit
df5dba8384
25
README.md
25
README.md
@ -1,7 +1,7 @@
|
||||
# redtimer
|
||||
|
||||
#### 项目介绍
|
||||
redtimer是本人纯手工精心编写的一个任务定时调度器,
|
||||
redtimer是本人纯手工精心编写的一个任务定时调度器,全部代码均自己编写实现;
|
||||
功能包含**定时和时间解析**两部分功能;
|
||||
编写她的意图,用更少的代码满足自己的业务功能需求,让其他业务代码更佳的随心所欲;
|
||||
|
||||
@ -13,19 +13,22 @@ redtimer是本人纯手工精心编写的一个任务定时调度器,
|
||||
|
||||
|
||||
#### 安装使用教程
|
||||
创建启动定时任务
|
||||
```
|
||||
TimerExecutor timerExecutor = new TimerExecutor(1);
|
||||
timerExecutor.add(new TaskImpl("a1", new ScheduledExpres("0 2 * * *"));//定时每天2点执行
|
||||
timerExecutor.start();
|
||||
请看测试案例,以及阅读详细源码,所有的代码也就几百行;
|
||||
Task task1 = new TaskImpl("a1", new ScheduledExpres("1-40 * * * *"));//1-40,定时每分钟执行
|
||||
Task task2 = new TaskImpl("a1", new ScheduledCycle(1000 * 5));//a2定时每5s执行
|
||||
|
||||
timerExecutor.add(task1, task2);//添加任务 task1,task2
|
||||
```
|
||||
#### 参与贡献
|
||||
你可以做这些
|
||||
1. Fork 本项目
|
||||
2. 新建 Feat_xxx 分支
|
||||
3. 提交代码
|
||||
4. 新建 Pull Request
|
||||
5. **提出你的宝贵意见**
|
||||
|
||||
支持定时计划修改
|
||||
```
|
||||
//修改a1 每2s执行一次
|
||||
task.setScheduled(new ScheduledCycle(2000 * 1));
|
||||
timerExecutor.add(task);
|
||||
```
|
||||
请看测试案例,以及阅读详细源码,所有的代码也就几百行;
|
||||
|
||||
#### 关于
|
||||
redbbs 交流群:527523235
|
||||
|
@ -24,6 +24,12 @@ public abstract class AbstractTask implements Task {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScheduled(Scheduled scheduled) {
|
||||
this.scheduled = scheduled;
|
||||
this.theTime = scheduled.theTime().toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextTime(){
|
||||
LocalDateTime next = scheduled.nextTime();
|
||||
@ -35,6 +41,8 @@ public abstract class AbstractTask implements Task {
|
||||
}
|
||||
@Override
|
||||
public long theTime(){
|
||||
LocalDateTime next = scheduled.theTime();
|
||||
this.theTime = next.toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
||||
return theTime;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,41 @@
|
||||
package com.lxyer.timer;
|
||||
|
||||
import com.lxyer.timer.scheduled.Scheduled;
|
||||
|
||||
/**
|
||||
* @author: liangxianyou at 2018/8/5 19:32.
|
||||
*/
|
||||
public interface Task extends Runnable{
|
||||
|
||||
/**
|
||||
* 得到任务名称
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* 设置任务执行计划
|
||||
*
|
||||
* @param scheduled
|
||||
*/
|
||||
void setScheduled(Scheduled scheduled);
|
||||
|
||||
/**
|
||||
* 得到下一次执行计划的时间,并设置thenTime
|
||||
* @return
|
||||
*/
|
||||
long nextTime();
|
||||
|
||||
/**
|
||||
* 任务即将执行的时间点
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
long theTime();
|
||||
|
||||
/**
|
||||
* 执行任务
|
||||
*/
|
||||
void run();
|
||||
}
|
||||
|
@ -12,16 +12,26 @@ public class TimerExecutor {
|
||||
|
||||
public TimerExecutor(int n) {
|
||||
executor = Executors.newFixedThreadPool(n);
|
||||
start();
|
||||
}
|
||||
|
||||
public void add(Task task){
|
||||
queue.put(task);
|
||||
public void add(Task ... task){
|
||||
for (Task t : task) {
|
||||
queue.put(t);
|
||||
}
|
||||
}
|
||||
private void add(Task task, boolean upTime){
|
||||
if (upTime) task.nextTime();
|
||||
queue.put(task);
|
||||
}
|
||||
|
||||
public Task remove(String name){
|
||||
return queue.remove(name);
|
||||
}
|
||||
public Task get(String name){
|
||||
return queue.get(name);
|
||||
}
|
||||
|
||||
|
||||
public void start() {
|
||||
new Thread(()->{
|
||||
|
@ -7,6 +7,7 @@ import java.util.Set;
|
||||
/**
|
||||
* Created by liangxianyou at 2018/7/23 14:07.
|
||||
*/
|
||||
@SuppressWarnings("Duplicates")
|
||||
class TimerQueue{
|
||||
Object lock = new Object();
|
||||
Task[] queue = new Task[128];
|
||||
@ -26,7 +27,6 @@ class TimerQueue{
|
||||
|
||||
for (int i = size+1; i > inx; i--) {
|
||||
queue[i] = queue[i-1];
|
||||
queue[i-1] = null;
|
||||
}
|
||||
queue[inx] = task;
|
||||
|
||||
@ -38,7 +38,7 @@ class TimerQueue{
|
||||
|
||||
Task take() throws InterruptedException {
|
||||
synchronized (lock){
|
||||
if (size == 0) lock.wait();
|
||||
while (size == 0) lock.wait(10);//循环避免非put线程唤醒空异常
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long nextTime = queue[0].theTime();
|
||||
@ -59,21 +59,33 @@ class TimerQueue{
|
||||
}
|
||||
|
||||
Task remove(String name){
|
||||
return get(name, true);
|
||||
}
|
||||
|
||||
Task get(String name){
|
||||
return get(name, false);
|
||||
}
|
||||
|
||||
private Task get(String name, boolean remove) {
|
||||
synchronized (lock){
|
||||
if(!names.contains(name)) return null;
|
||||
|
||||
Task take = null;
|
||||
for (int i = 0; i < size-1; i++) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (name.equals(queue[i].getName())){
|
||||
take = queue[i];
|
||||
if (!remove) break;
|
||||
while (i < size+1){
|
||||
queue[i] = queue[i+1];
|
||||
queue[i+1] = null;
|
||||
i++;
|
||||
}
|
||||
names.remove(name);
|
||||
size--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lock.notify();
|
||||
return take;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,18 @@ public class ScheduledCycle implements Scheduled {
|
||||
|
||||
private LocalDateTime theTime;
|
||||
private long period;
|
||||
private TemporalUnit unit = ChronoUnit.SECONDS;
|
||||
private TemporalUnit unit = ChronoUnit.MILLIS;
|
||||
|
||||
|
||||
public ScheduledCycle(long period) {
|
||||
this.theTime = LocalDateTime.now();
|
||||
this.period = period;
|
||||
}
|
||||
public ScheduledCycle(long period,TemporalUnit unit) {
|
||||
this.theTime = LocalDateTime.now();
|
||||
this.period = period;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public ScheduledCycle(LocalDateTime startTime, long period) {
|
||||
this.theTime = startTime;
|
||||
@ -25,7 +36,7 @@ public class ScheduledCycle implements Scheduled {
|
||||
|
||||
@Override
|
||||
public LocalDateTime nextTime() {
|
||||
return theTime.plus(period, unit);
|
||||
return theTime = theTime.plus(period, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -21,24 +21,27 @@ public class ScheduledExpres implements Scheduled{
|
||||
private int[] days;
|
||||
private int[] monthes;
|
||||
private int[] weeks;
|
||||
private String[] cfgArr;
|
||||
|
||||
private String cfg;
|
||||
private String[] cfgArr;
|
||||
private LocalDateTime theTime;
|
||||
private int _y,_M,_d,_H,_m;
|
||||
|
||||
public ScheduledExpres(String cfg){
|
||||
this.cfg = cfg;
|
||||
this.theTime = LocalDateTime.now();
|
||||
initTheTime(cfg);
|
||||
initTheTime();
|
||||
}
|
||||
|
||||
public ScheduledExpres(final LocalDateTime startTime, String cfg){
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
this.theTime = now.isAfter(startTime)? now : startTime;
|
||||
initTheTime(cfg);
|
||||
this.cfg = cfg;
|
||||
initTheTime();
|
||||
}
|
||||
|
||||
//寻找初始合法时间
|
||||
public void initTheTime( String cfg) {
|
||||
public void initTheTime() {
|
||||
year = theTime.getYear();
|
||||
month = theTime.getMonthValue();
|
||||
cfgArr = cfg.split(" ");
|
||||
@ -103,7 +106,7 @@ public class ScheduledExpres implements Scheduled{
|
||||
*/
|
||||
@Override
|
||||
public LocalDateTime nextTime(){
|
||||
return carry("m");
|
||||
return theTime = carry("m");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.lxyer.timer;
|
||||
|
||||
import com.lxyer.timer.scheduled.ScheduledCycle;
|
||||
import com.lxyer.timer.scheduled.ScheduledExpres;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -19,16 +20,24 @@ public class TimerTest {
|
||||
* 启动定时器测试,
|
||||
*/
|
||||
@Test
|
||||
public void t2(){
|
||||
public void t2() throws InterruptedException {
|
||||
TimerExecutor timerExecutor = new TimerExecutor(1);
|
||||
timerExecutor.add(new TaskImpl("a1", new ScheduledExpres(LocalDateTime.now(), "1-40/2 * * * *")));//1-40,定时每分钟执行
|
||||
timerExecutor.start();
|
||||
Task t1 = new TaskImpl("a1", new ScheduledExpres("1-40 * * * *"));//1-40,定时每分钟执行
|
||||
TaskImpl t2 = new TaskImpl("a2", new ScheduledCycle(5000 * 1));
|
||||
|
||||
try {
|
||||
Thread.sleep(1500_000000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
timerExecutor.add(t1, t2);
|
||||
|
||||
//60s后修改a1 每2s执行一次
|
||||
Thread.sleep(1000 * 60);
|
||||
//task = timerExecutor.get("a1");
|
||||
if (t1 != null){
|
||||
t1.setScheduled(new ScheduledCycle(2000 * 1));
|
||||
timerExecutor.add(t1);
|
||||
}
|
||||
|
||||
|
||||
Thread.sleep(1500_000000);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,7 +142,28 @@ public class TimerTest {
|
||||
08 18 * 7,8 4
|
||||
"task1", "1 22-23 * * 7"
|
||||
*/
|
||||
Task task = new TaskImpl("task1", new ScheduledExpres("1 22-23 * * 7"));
|
||||
Task task = new TaskImpl("task1", new ScheduledExpres("1 22-23 * * 7")){
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("----");
|
||||
System.out.println(new SimpleDateFormat("0: yyyy-MM-dd HH:mm:ss").format(theTime()));
|
||||
System.out.println(new SimpleDateFormat("1: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("2: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
/*System.out.println(new SimpleDateFormat("3: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("4: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("5: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("6: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("7: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("8: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("9: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("10: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("11: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("12: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||
System.out.println(new SimpleDateFormat("13: yyyy-MM-dd HH:mm:ss").format(nextTime()));*/
|
||||
}
|
||||
};
|
||||
task.run();
|
||||
task.setScheduled(new ScheduledCycle(1000 * 5));//定时每秒执行
|
||||
task.run();
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user