欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

通过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);
    }
}

通过Java反射机制动态修改TimerTask的执行周期并立即生效

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);
    }
}

通过Java反射机制动态修改TimerTask的执行周期并立即生效

参考文章链接:
https://www.iteye.com/blog/chen-yongkai-1673241
https://blog.csdn.net/yasi_xi/article/details/25626113