通过Java反射机制动态修改TimerTask的执行周期并立即生效
程序员文章站
2022-06-09 15:08:55
...
import java.lang.reflect.Field;
import java.util.Date;
import java.util.TimerTask;
/**
* SendMailTask
*/
public abstract class SendMailTask extends TimerTask {
long period = 0;
public void setPeriod(long period) {
Date now = new Date();
// 设置下一次执行时间i
long nextExecutionTime = now.getTime() + period;
setDeclaredField(TimerTask.class, this, "nextExecutionTime", nextExecutionTime);
// 修改执行周期
setDeclaredField(TimerTask.class, this, "period", period);
}
//通过反射修改字段的值
static boolean setDeclaredField(Class<?> clazz, Object obj, String name, Object value) {
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
field.set(obj, value);
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
}
测试:
import SendMailTask;
import java.time.LocalDateTime;
import java.util.Timer;
public class TimerTest2 {
static int i = 0;
static int k = 0;
static int n = 0;
/**
* 获取两数之间的随机数
* @param m
* @param n
* @return
*/
public static int getRandom(int m, int n) {
int max = Math.max(m,n);
int min = Math.min(m,n);
int mid = max - min;
// 产生随机数
int num = (int) (Math.random() * (mid + 1)) + min;
return num;
}
public static void main(String[] args) {
int total = 10;
int pause = 5;
int interval = 1;
// timer
Timer timer = new Timer(); // 定时任务
SendMailTask task = new SendMailTask() {
int count = 0; // 循环计数器
// timerTask执行体
@Override
public synchronized void run() {
++k;
++n;
System.out.println("hello,这是第"+k+"次输出!当前时间:"+ LocalDateTime.now());
i++;
count++;
if (count == total) {
System.err.println("完成时间: " + LocalDateTime.now());
timer.cancel(); // 取消定时器
}
// 每发完pause,暂停一段时间
if (count % pause == 0 && count != total) {
try {
System.out.println("打印完" + pause + "条了," + interval + "分钟后继续: " + LocalDateTime.now());
n = 0;
Thread.sleep(interval * 60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(n > 0 && n % 3 == 0) {
try {
n = 0;
System.out.println("2秒后继续。。。。"+ LocalDateTime.now());
Thread.sleep(2000);
//wait(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 修改任务周期
if(i>0 && i % 3 == 0) {
setPeriod(5000);
System.out.println("间隔修改为5秒。。。"+ LocalDateTime.now());
}
}
};
timer.schedule(task, 2000, 3000);
}
}
import SendMailTask;
import java.time.LocalDateTime;
import java.util.Timer;
public class TimerTest2 {
static int i = 0;
static int k = 0;
static int n = 0;
/**
* 获取两数之间的随机数
* @param m
* @param n
* @return
*/
public static int getRandom(int m, int n) {
int max = Math.max(m,n);
int min = Math.min(m,n);
int mid = max - min;
// 产生随机数
int num = (int) (Math.random() * (mid + 1)) + min;
return num;
}
public static void main(String[] args) {
int total = 10;
int pause = 5;
int interval = 1;
int min = 5;
int max = 20;
int amount = 3;
// timer
Timer timer = new Timer(); // 定时任务
SendMailTask task = new SendMailTask() {
int count = 0; // 循环计数器
// timerTask执行体
@Override
public synchronized void run() {
++k;
++n;
System.out.println("hello,这是第"+k+"次输出!当前时间:"+ LocalDateTime.now());
i++;
count++;
if (count == total) {
System.err.println("完成时间: " + LocalDateTime.now());
timer.cancel(); // 取消定时器
}
// 每发完pause,暂停一段时间
if (count % pause == 0 && count != total) {
try {
System.out.println("打印完" + pause + "条了," + interval + "分钟后继续: " + LocalDateTime.now());
n = 0;
i = 0;
Thread.sleep(interval * 60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(n > 0 && n % amount == 0) {
try {
n = 0;
int seconds1 = getRandom(min,max);
System.out.println(seconds1 +"秒后继续。。。。"+ LocalDateTime.now());
Thread.sleep(seconds1 * 1000 );
//wait(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 修改任务周期
if(i>0 && i % amount == 0) {
i = 0;
int seconds2 = Math.round(getRandom(min,max) / amount);
setPeriod(seconds2 * 1000);
System.out.println("间隔修改为"+ seconds2 + "秒。。。"+ LocalDateTime.now());
}
}
};
timer.schedule(task, 2000, Math.round( (getRandom(min,max) / amount) * 1000 )+1);
}
}
参考文章链接:
https://www.iteye.com/blog/chen-yongkai-1673241
https://blog.csdn.net/yasi_xi/article/details/25626113