关于cron表达式的一个问题,不知是不是bug...

北北啊我是 2020-04-29 11:01:19
今天用cron表达式做定时任务(threadPoolTaskScheduler.schedule(Runnable task, Trigger trigger)这个方法)的周期, 遇到个怪事, 网上搜了半天没搜到, 简单来说就是有个需求每隔几秒进行一个操作, 表达式我这么写的"0/7 * * * * ? " 但是输出时候发现 输出的时间是这种 : 7秒(s) 14s 21s 28s 35s 42s 49s 56s 重点来了 下一分钟起始的00s又输出了一次... 然后我就思考 觉得表达式不应该是 0/7开头 毕竟这种的起始时间是每分钟的00秒 对吧 我就改了 改成了"*/7 * * * * ? " 结果依然不行 .. 还是每分钟的00秒都会输出.. gg.. 可能没说清 看图
后来换了sheduleAtFixedRate方法,能满足需求, 但是不懂为啥schdule用cron表达式换了*/7 这种方式还是依然每分钟的00秒会跑一次任务.. 实在网上没查到方法.. 求大佬明示!
...全文
452 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
北北啊我是 2020-05-14
  • 打赏
  • 举报
回复
up一下 期待大佬
北北啊我是 2020-05-07
  • 打赏
  • 举报
回复
引用 5 楼 qybao 的回复:
[quote=引用 4 楼 北北啊我是 的回复:][quote=引用 3 楼 qybao 的回复:] [quote=引用 2 楼 北北啊我是 的回复:] 首先感谢大佬回复, 果然是关于表达式的理解不到位... 不过想着"因为你的分钟没有限定,所以分钟变了以后0秒也符合表达式,所以0秒也会执行"还是有点模糊, 能再详细说说嘛大佬, 谢了!
"*/7 * * * * ? " 因为秒为*,本来每分钟内每秒都执行,但是由于秒有/7限制,所以每隔7秒才执行,但是分钟变化了以后,*/7秒又在新的分钟里被刷新,*又代表任意秒,所有0秒就执行,又由于有/7限制,所有每7秒才执行,如此循环知道分钟又更新。 所以要么你就按这个周期执行,要么就把分钟,乃至到小时分段限制。 7秒一个周期,那么7分钟后就会回到起点,所有也就要分段写7分钟[/quote] 再次感谢大佬指点 懂了您的意思 按照您说的方法我计算了一下 不过七秒的话 我算的是要写六种cron表达式啊  是七种吗? 这个图是我写的六种表达式, 您看看
public static void main(String[] args) {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(6);
        scheduler.initialize();
        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("0/7 0,6,12,18,24,30,36,42,48,54 * * * ?"));

        省略。。},new CronTrigger("3/7 1,7,13,19,25,31,37,43,49,55 * * * ?"));

        省略。。},new CronTrigger("6/7 2,8,14,20,26,32,38,44,50,56 * * * ?"));

        省略。。},new CronTrigger("5/7 3,9,15,21,27,33,39,45,51,57 * * * ?"));

        省略。。},new CronTrigger("1/7 4,10,16,22,28,34,40,46,52,58 * * * ?"));

        省略。。},new CronTrigger("4/7 5,11,17,23,29,35,41,47,53,59 * * * ?"));

    }
[/quote]还少了个2/7开头的吧?[/quote]
public static void main(String[] args) {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(6);
        scheduler.initialize();
        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("0/7 0,7,14,21,28,35,42,49,56 * * * ?"));

        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("3/7 1,8,15,22,29,36,43,50,57 * * * ?"));

        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("6/7 2,9,16,23,30,37,44,51,58 * * * ?"));

        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("2/7 3,10,17,24,31,38,45,52,59 * * * ?"));

        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("5/7 4,11,18,25,32,39,46,53 * * * ?"));

        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("1/7 5,12,19,26,33,40,47,54 * * * ?"));

        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("4/7 6,13,20,27,34,41,48,55 * * * ?"));

    }
再次跪谢大佬!!!
北北啊我是 2020-05-07
  • 打赏
  • 举报
回复
引用 5 楼 qybao 的回复:
[quote=引用 4 楼 北北啊我是 的回复:][quote=引用 3 楼 qybao 的回复:] [quote=引用 2 楼 北北啊我是 的回复:] 首先感谢大佬回复, 果然是关于表达式的理解不到位... 不过想着"因为你的分钟没有限定,所以分钟变了以后0秒也符合表达式,所以0秒也会执行"还是有点模糊, 能再详细说说嘛大佬, 谢了!
"*/7 * * * * ? " 因为秒为*,本来每分钟内每秒都执行,但是由于秒有/7限制,所以每隔7秒才执行,但是分钟变化了以后,*/7秒又在新的分钟里被刷新,*又代表任意秒,所有0秒就执行,又由于有/7限制,所有每7秒才执行,如此循环知道分钟又更新。 所以要么你就按这个周期执行,要么就把分钟,乃至到小时分段限制。 7秒一个周期,那么7分钟后就会回到起点,所有也就要分段写7分钟[/quote] 再次感谢大佬指点 懂了您的意思 按照您说的方法我计算了一下 不过七秒的话 我算的是要写六种cron表达式啊  是七种吗? 这个图是我写的六种表达式, 您看看
public static void main(String[] args) {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(6);
        scheduler.initialize();
        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("0/7 0,6,12,18,24,30,36,42,48,54 * * * ?"));

        省略。。},new CronTrigger("3/7 1,7,13,19,25,31,37,43,49,55 * * * ?"));

        省略。。},new CronTrigger("6/7 2,8,14,20,26,32,38,44,50,56 * * * ?"));

        省略。。},new CronTrigger("5/7 3,9,15,21,27,33,39,45,51,57 * * * ?"));

        省略。。},new CronTrigger("1/7 4,10,16,22,28,34,40,46,52,58 * * * ?"));

        省略。。},new CronTrigger("4/7 5,11,17,23,29,35,41,47,53,59 * * * ?"));

    }
[/quote]还少了个2/7开头的吧?[/quote] 再次感谢大佬回复, 按您说的从新算了下 确实少了2/7开头的 不过!!! 又出现问题了.. 您看图 不知道为什么有的线程(分钟)是从中间某个值开始跑的,而不是从开头跑,而有的线程(分钟)就是正确的... 代码在楼下, 方便的话您可以跑一下试试...?
北北啊我是 2020-05-01
  • 打赏
  • 举报
回复
引用 3 楼 qybao 的回复:
[quote=引用 2 楼 北北啊我是 的回复:] 首先感谢大佬回复, 果然是关于表达式的理解不到位... 不过想着"因为你的分钟没有限定,所以分钟变了以后0秒也符合表达式,所以0秒也会执行"还是有点模糊, 能再详细说说嘛大佬, 谢了!
"*/7 * * * * ? " 因为秒为*,本来每分钟内每秒都执行,但是由于秒有/7限制,所以每隔7秒才执行,但是分钟变化了以后,*/7秒又在新的分钟里被刷新,*又代表任意秒,所有0秒就执行,又由于有/7限制,所有每7秒才执行,如此循环知道分钟又更新。 所以要么你就按这个周期执行,要么就把分钟,乃至到小时分段限制。 7秒一个周期,那么7分钟后就会回到起点,所有也就要分段写7分钟[/quote] 再次感谢大佬指点 懂了您的意思 按照您说的方法我计算了一下 不过七秒的话 我算的是要写六种cron表达式啊 😂 是七种吗? 这个图是我写的六种表达式, 您看看
public static void main(String[] args) {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(6);
        scheduler.initialize();
        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("0/7 0,6,12,18,24,30,36,42,48,54 * * * ?"));

        省略。。},new CronTrigger("3/7 1,7,13,19,25,31,37,43,49,55 * * * ?"));

        省略。。},new CronTrigger("6/7 2,8,14,20,26,32,38,44,50,56 * * * ?"));

        省略。。},new CronTrigger("5/7 3,9,15,21,27,33,39,45,51,57 * * * ?"));

        省略。。},new CronTrigger("1/7 4,10,16,22,28,34,40,46,52,58 * * * ?"));

        省略。。},new CronTrigger("4/7 5,11,17,23,29,35,41,47,53,59 * * * ?"));

    }
qybao 2020-05-01
  • 打赏
  • 举报
回复
引用 4 楼 北北啊我是 的回复:
[quote=引用 3 楼 qybao 的回复:] [quote=引用 2 楼 北北啊我是 的回复:] 首先感谢大佬回复, 果然是关于表达式的理解不到位... 不过想着"因为你的分钟没有限定,所以分钟变了以后0秒也符合表达式,所以0秒也会执行"还是有点模糊, 能再详细说说嘛大佬, 谢了!
"*/7 * * * * ? " 因为秒为*,本来每分钟内每秒都执行,但是由于秒有/7限制,所以每隔7秒才执行,但是分钟变化了以后,*/7秒又在新的分钟里被刷新,*又代表任意秒,所有0秒就执行,又由于有/7限制,所有每7秒才执行,如此循环知道分钟又更新。 所以要么你就按这个周期执行,要么就把分钟,乃至到小时分段限制。 7秒一个周期,那么7分钟后就会回到起点,所有也就要分段写7分钟[/quote] 再次感谢大佬指点 懂了您的意思 按照您说的方法我计算了一下 不过七秒的话 我算的是要写六种cron表达式啊  是七种吗? 这个图是我写的六种表达式, 您看看
public static void main(String[] args) {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(6);
        scheduler.initialize();
        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("ThreadName==="+Thread.currentThread()+"==="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            }
        },new CronTrigger("0/7 0,6,12,18,24,30,36,42,48,54 * * * ?"));

        省略。。},new CronTrigger("3/7 1,7,13,19,25,31,37,43,49,55 * * * ?"));

        省略。。},new CronTrigger("6/7 2,8,14,20,26,32,38,44,50,56 * * * ?"));

        省略。。},new CronTrigger("5/7 3,9,15,21,27,33,39,45,51,57 * * * ?"));

        省略。。},new CronTrigger("1/7 4,10,16,22,28,34,40,46,52,58 * * * ?"));

        省略。。},new CronTrigger("4/7 5,11,17,23,29,35,41,47,53,59 * * * ?"));

    }
[/quote]还少了个2/7开头的吧?
qybao 2020-04-30
  • 打赏
  • 举报
回复
那是你的cron表达式不对
"0/7 * * * * ? " 表示任意时间的0秒开始每隔7秒执行
"*/7 * * * * ? " 表示任意时间的任意秒开始每隔7秒执行(因为你的分钟没有限定,所以分钟变了以后0秒也符合表达式,所以0秒也会执行)
所以你这种情况,应该采用分段,即

"0/7 1 * * * ? "
"3/7 2 * * * ? "
。。。
等等,自己推算吧
qybao 2020-04-30
  • 打赏
  • 举报
回复
引用 2 楼 北北啊我是 的回复:
首先感谢大佬回复, 果然是关于表达式的理解不到位... 不过想着"因为你的分钟没有限定,所以分钟变了以后0秒也符合表达式,所以0秒也会执行"还是有点模糊, 能再详细说说嘛大佬, 谢了!

"*/7 * * * * ? " 因为秒为*,本来每分钟内每秒都执行,但是由于秒有/7限制,所以每隔7秒才执行,但是分钟变化了以后,*/7秒又在新的分钟里被刷新,*又代表任意秒,所有0秒就执行,又由于有/7限制,所有每7秒才执行,如此循环知道分钟又更新。
所以要么你就按这个周期执行,要么就把分钟,乃至到小时分段限制。
7秒一个周期,那么7分钟后就会回到起点,所有也就要分段写7分钟
北北啊我是 2020-04-30
  • 打赏
  • 举报
回复
引用 1 楼 qybao 的回复:
那是你的cron表达式不对 "0/7 * * * * ? " 表示任意时间的0秒开始每隔7秒执行 "*/7 * * * * ? " 表示任意时间的任意秒开始每隔7秒执行(因为你的分钟没有限定,所以分钟变了以后0秒也符合表达式,所以0秒也会执行) 所以你这种情况,应该采用分段,即 "0/7 1 * * * ? " "3/7 2 * * * ? " 。。。 等等,自己推算吧
首先感谢大佬回复, 果然是关于表达式的理解不到位... 不过想着"因为你的分钟没有限定,所以分钟变了以后0秒也符合表达式,所以0秒也会执行"还是有点模糊, 能再详细说说嘛大佬, 谢了!

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧