精华内容
下载资源
问答
  •   在看《Java并发实战》的时候,看到了Timer的例子,就想起来刚开始工作的时候有一个功能,定时的查询数据并推送且,参数大概就是sql相关参数,定时周期,定时任务的开启和关闭。用Timer简单是写个demo。 /** * @...

    文章目录


      在看《Java并发实战》的时候,看到了Timer的例子,就想起来刚开始工作的时候有一个功能,定时的查询数据并推送且,参数大概就是sql相关参数,定时周期,定时任务的开启和关闭。用Timer简单是写个demo。

    /**
     * @author hqh
     * @create 2021/6/23 10:18
     * @description
     * @mail xxx
     */
    public class DynamicTimer {
        //模拟数据库存储的任务参数  key:任务id,value:任务参数
        public static Map<Integer,String> jobs = new HashMap(){
            {
                put(1,"任务一");
                put(2,"任务二");
                put(3,"任务三");
            }
        };
        //key:任务id,value:timer类 管理所有正在运行中的timer
        public static Map<Integer,Timer> timers=new HashMap<>();
    
        public static void main(String[] args) throws Exception{
    		//每次开启定时任务都new 一个timer存在timers中
    		//每次关闭定时任务都保存相关数据并从timer remove
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    //模拟从数据库拿出执行任务的逻辑或参数并执行,定时任务时间也可以指定
                    System.out.println(jobs.get(1));
                }
            },new Date(),5000);
            //开启定时任务,放入map方便管理(停止)
            timers.put(1,timer);
            Thread.sleep(16000);
            //结束任务
            timers.get(1).cancel();
            //移除timer
            timers.remove(1);
        }
    }
    
    展开全文
  • 可以通过java的Timer类来进行定时调用,下面是有关Timer的一些相关知识。  其实Timer来讲是一个调度器,而TimerTask呢只是一个实现了run方法的一个类,而具体的TimerTask需要由你自己来实现,例如这样:  Timer ...
  • 文章目录GO的定时器Timer定时任务cronTimer 是什么?Timer 如何使用?基本使用Time 延时使用停止定时器重置定时器Ticker 是什么?Ticker 如何使用?简单应用`Ticker`来一个通用版本的 DEMOcron 是什么?cron 如何...

    GO的定时器Timer 和定时任务cron

    上次我们说到了GO 中 swaggo 的应用,咱们来回顾一下

    • swaggo 是什么
    • swagger 是什么
    • 如何使用 swaggo
    • 如何测试 swaggo

    要是对GO 中 swaggo 的应用还有点兴趣的话,可以查看文章 工作中后端是如何将API提供出去的?swaggo很不错

    之后我们可以来一次 swaggo 的原理分享,细细的了解一下swaggo是如何生成swagger 文档的

    今天咱们来看看 GO 里面的 **定时器 Timer 和 定时任务 cron **

    咱们今天还是来看看 定时器 timer 和 定时任务 cron 如何使用,关于他们的原理,咱们后续文章会详细分享

    Timer 是什么?

    是 GO 中提供一个 定时器包,主要是用 time.Timer

    timer 实际上是一种单一事件的定时器

    也就是说,经过指定的时间后触发一个事件,这个事件通过其本身提供的 通道 进行通知 , 因为Timer只执行一次就结束,所以叫他单一事件

    TimerTicker最重要的区别之一 就是这里了

    大致流程是这个样子的:

    Go 运行时会启动一个单独的 协程

    该协程 执行了一个 timerproc 的函数,维护了一个 最小堆

    该协程会定期被唤醒并读取堆顶的 timer 对象,执行该 timer 对象对应的函数(就是在 timer.C 中发送一条数据,用于触发定时器)

    执行完毕后就会从最小堆中移除该 timer 对象

    咱们创建的 time.Timer ,实际上就是在这个最小堆中添加一个 timer 对象实例,那么我们需要停止定时器,也就是使用 timer.Stop的时候,就是从这个堆里面删除对应的 timer 对象

    本文先不细细说明实际原理,咱们先会简单应用它,后续会详细分享

    万事开头难,然后中间难,最后结尾难

    Timer 如何使用?

    咱们简单看看 Timer 对应的数据结构

    位置在: src/time/sleep.go:Timer

    Timer代表一次定时,时间到来后只发生一个事件
    只发生一次,这里尤为重要

    Timer对外仅暴露一个通道,指定的时间到了,就会往该通道中写入系统时间,时间到了就触发一次事件,只会触发一次,因为时间只会到一次

    type Timer struct { 
        C <-chan Time
        r runtimeTimer
    }
    

    咱们分别从如下几个场景使用一下 Timer

    • 基本使用
    • Time 延时使用
    • 停止定时器
    • 重置定时器

    基本使用

    咱们设置一个 1s 中的定时器,这个定时器只会触发一次

    创建一个定时器:

    func New*Timer*(d Duration) Timer

    指定一个时间即可创建一个TimerTimer一经创建便开始计时,不需要额外的启动命令

    func main() {
        // 创建一个 Timer
       myT := time.NewTimer(1 * time.Second)
        // 从通道中读取数据,若读取得到,说明时间到了
       <- myT.C
       fmt.Println(" 1 s 时间到")
    
       for {}
    }
    

    Time 延时使用

    设置一个 1 秒的定时,再延时 2 秒

    func main() {
        // 创建一个 Timer
       myT := time.NewTimer(1 * time.Second)
       <- myT.C
       fmt.Println(" 1 s 时间到 ",time.Now().Unix())
       
       // 延时 2 秒
       <-time.After(2 * time.Second)
       fmt.Println(" 2 s 时间到 ",time.Now().Unix())
       
       for {}
    }
    

    运行代码执行效果如下:

     1 s 时间到  1624757781
     2 s 时间到  1624757783
    

    GO 还提供了一个函数 AfterFunc

    func AfterFunc(d Duration, f func()) *Timer

    也是可以做到延迟的效果,更好的是,延迟了之后,能够执行我们填入的函数

    停止定时器

    Timer 创建后可以随时停止,咱们可以使用time.Stop()停止定时器:

    func (t *Timer) Stop() bool

    Stop()函数返回值是 bool,要么是 true , 要么是 false , 代表的含义是 定时器是否超时

    • true

    定时器超时前停止,后续不会再有事件发送了

    • false

    定时器是在超时后,停止的

    写一个DEMO , 设置 1 s 的定时器

    若在到了1 s ,则进行打印,说明已经超时

    若没有到 1 s ,通道就已经关闭了,则未超时

    func testChannelTimeout(conn chan int) bool {
       // 设置 1 秒的定时器,若在到了1 s ,则进行打印,说明已经超时
       timer := time.NewTimer(1 * time.Second)
    
       select {
       case <-conn:
           if (timer.Stop()){
               fmt.Println("timer.Stop()")
           }
          return true
       case <-timer.C: // timer 通道超时
          fmt.Println("timer Channel timeout!")
          return false
       }
    }
    
    func main() {
    
       ch := make(chan int, 1)
        // 若打开如下语句,则可以正常关闭定时器
        // 若注释如下语句,则关闭定时器超时
       //ch <- 1
       go testChannelTimeout(ch)
    
       for {}
    }
    

    上述代码中,是否关闭定时器超时,跟另外一个辅助通道息息相关

    若打开如下语句,则可以正常关闭定时器

    若注释如下语句,则关闭定时器超时

    ch <- 1

    重置定时器

    开局设置一个鱼的记忆,7秒的定时器

    立刻将定时器重置成 1 秒的定时器

    func main() {
       // 创建一个 Timer 鱼的记忆
       fmt.Println(" 开始 ", time.Now().Unix())
       myT := time.NewTimer(7 * time.Second)
       // 重置定时器为 1 s
       myT.Reset(1 * time.Second)
       <-myT.C
       fmt.Println(" 1 s 时间到 ", time.Now().Unix())
    
       for {}
    }
    

    运行上述代码后,效果如下:

     开始  1624759572
     1 s 时间到  1624759573
    

    上述Timer 都是触发一次,生效一次,这样并不能满足所有场景,例如周期性定时执行的场景就不满足了

    咱们可以使用 GO 里面的 Ticker

    Ticker 是什么?

    Ticker也是定时器,不过他是一个周期性的定时器,

    也就是说,他用于周期性的触发一个事件,通过Ticker本身提供的管道将事件传递出去的

    Ticker对外仅暴露一个通道,指定的时间到了,就往该通道中写入系统时间,也即一个事件。此处的时间到了,只的是周期性的时间到了

    Ticker 如何使用?

    位置在: src/time/tick.go:Timer

    type Ticker structtype Timer struct { 一模一样

    // A Ticker holds a channel that delivers ``ticks'' of a clock
    // at intervals.
    type Ticker struct {
       C <-chan Time // The channel on which the ticks are delivered.
       r runtimeTimer
    }
    

    关于创建定时器 和 关闭定时器 和 上述的 Timer方法类似,咱们一起列举出来

    创建Ticker 定时器(强调:这是一个周期性的定时器)

    func NewTicker(d Duration) *Ticker

    关闭Ticker 定时器

    func (t *Ticker) Stop()

    简单应用Ticker

    设置 2 秒的 周期性定时器 Ticker

    ticker := time.NewTicker(2 * time.Second)
    defer ticker.Stop()
    
    // 若通道为空,则阻塞
    // 若通道有数据,则读取
    // 若通道关闭,则退出
    for range ticker.C {
       fmt.Println("ticker ticker ticker ...")
    }
    

    来一个通用版本的 DEMO

    周期性的执行任务,我们可以灵活设置时间,和具体处理的任务

    • 封装Ticker的调用
    // 定义函数类型
    type Fn func() error
    
    // 定时器中的成员
    type MyTicker struct {
    	MyTick *time.Ticker
    	Runner Fn
    }
    
    func NewMyTick(interval int, f Fn) *MyTicker {
    	return &MyTicker{
    		MyTick: time.NewTicker(time.Duration(interval) * time.Second),
    		Runner: f,
    	}
    }
    
    // 启动定时器需要执行的任务
    func (t *MyTicker) Start() {
    	for {
    		select {
    		case <-t.MyTick.C:
    			t.Runner()
    		}
    	}
    }
    
    func testPrint(){
    	fmt.Println(" 滴答 1 次")
    }
    
    func main() {
    	t := NewMyTick( 1 ,testPrint)
    	t.Start()
    }
    

    执行上述代码,运行效果:

    滴答 1 次
    滴答 1 次
    滴答 1...
    

    触发一次的Timer,周期性触发的Ticker,咱们都应用到了

    cron 是什么?

    看到 cron 小伙伴们应该不会陌生吧,用过 linux 的应该对 cron 还是有点想法的

    linux里面咱们可以使用 crontab -e 来设置定时任务,GO 里面,我们也可以是使用 cron 包来设置定时任务

    不过,linux里面 上述定时任务只支持 分钟以上级别

    咱们的 GO 可以支持到 秒级别

    cron 如何使用?

    使用的包:"github.com/robfig/cron"

    关于 cron 的基本语法和 在linux玩的时候类似,咱们来列举一下:

    // 每隔1秒执行一次
    */1 * * * * ?
    
    // 每隔1分钟执行一次
    0 */1 * * * ?
    
    // 每天0点执行一次
    0 0 0 * * ?
    
    // 每月1号凌晨1点执行一次
    0 0 1 1 * ?
    
    // 在1分、2分、3分执行一次
    0 1,2,3 * * * ?
    
    // 每天的0点、1点、2点执行一次
    0 0 0,1,2 * * ?
    

    解释一下上述的一些字符:

    匹配该字段的所有值 , 例如 */1 * * * * ? 第 2 个 * 就是代表 每一分钟

    • /

    表示增长间隔 ,例如 0 */1 * * * ? 表示,每一隔分钟执行一次

    枚举值

    例如秒, 可以写 1到59秒钟的任意数字, 1,3,5 * * * * ?,指的是每一分钟的 1 , 3 ,5秒 会执行任务

    其中时、分、秒的可选范围是 1-59

    日 可选范围是 1-31

    月 可选范围是 1-12

    年 可选范围是 1-12

    星期 可选范围是 0-6 表示 周日 - 周六

    表示一个范围, 例如 1-10/2 * * * * ? ,指每分钟的 1 -10,每隔 2 秒钟,执行任务

    • ?

    用于 表示 或者 星期

    来一个简单的例子

    设置 每隔 2 秒钟 执行一次任务

    func main() {
       i := 0
       c := cron.New()
       spec := "*/2 * * * * ?"
       err := c.AddFunc(spec, func() {
          i++
          fmt.Println("cron times : ", i)
       })
       if err != nil {
          fmt.Errorf("AddFunc error : %v",err)
          return 
       }
       c.Start()
    
       defer c.Stop()
       select {}
    }
    

    cron 用起来还是非常简单的,感兴趣的朋友,可以多多实践一下,关于他们的原理,咱么后续娓娓道来

    总结

    • Timer 是什么
    • Timer 如何使用
    • Ticker 是什么
    • Ticker 如何使用
    • cron 是什么
    • cron 如何使用

    欢迎点赞,关注,收藏

    朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

    好了,本次就到这里,下一次 GO 的日志如何玩

    技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

    我是小魔童哪吒,欢迎点赞关注收藏,下次见~

    展开全文
  • Timer任务定时器如何终止

    千次阅读 2019-10-15 19:42:30
    Timer timer = new Timer ( ) ; timer . schedule ( new TimerTask ( ) { @Override public void run ( ) { System . out . println ( "开始计划任务。" ) ; } } , time ) ; ...

    一个简单的计时器:

    		# do something ……
    		
    		long time = 1 * 1 * 1000L;
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("开始计划任务。");
                }
            }, time);
    

    开始计时后,过来1秒钟会开始计划任务。但是计划任务结束后会发现,其实程序还有还没有停止,如下eclipse的控制台还是会显示还在运行状态。
    在这里插入图片描述
    通过打断点,发现计划任务执行结束后,计时器的线程没有结束(本来应该已经结束了的)。
    在这里插入图片描述
    再次调试,发现又挂起了新的线程:
    在这里插入图片描述

    在计时器结束后,我们需要通过public void cancel()来取消这个线程,不然它会一直挂起。如果需要在外面终止计时器,也可以schedule()方法外面调用这个方法。

    		# do something ……
    		
    		long time = 1 * 1 * 1000L;
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("开始计划任务。");
                    timer.cancel();
                }
            }, time);
    

    参考:

    展开全文
  • 学习Windows服务制作;...修改Service1中的代码:如下 打开Service1 写入想要执行的操作等: 1 2 3 4 5 6 ...System.Timers.Timer timer1;...//定时调用接口 ...//系统即将关闭执行代码   base .OnShutdown();   }   }

    学习Windows服务制作;http://blog.csdn.net/u011966339/article/details/79549293

    修改Service1中的代码:如下

    打开Service1 写入想要执行的操作等:

    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
    public  partial  class  Service1 : ServiceBase
         {
             System.Timers.Timer timer1;   //计时器
             public  Service1()
             {
                 InitializeComponent();
             }
     
             protected  override  void  OnStart( string [] args)
             {
                 //服务开启执行代码
                 //定时调用接口
     
                 timer1 =  new  System.Timers.Timer();
                 timer1.Interval = 3000;   //设置计时器事件间隔执行时间
                 timer1.Elapsed +=  new  System.Timers.ElapsedEventHandler(timer1_Elapsed);
                 timer1.Enabled =  true ;
     
                 
     
             }
             /// <summary>
             /// 定时器 调用的方法
             /// </summary>
             /// <param name="sender"></param>
             /// <param name="e"></param>
             private  void  timer1_Elapsed( object  sender, System.Timers.ElapsedEventArgs e)
             {
                 var  client =  new  HttpClient();
                 client.BaseAddress =  new  Uri( "http://192.168.10.239:9000/" );//接口url
                 string  data = client.GetStringAsync( "ZyTest" ).Result; //接口action
             }
     
             protected  override  void  OnStop()
             {
                 //服务结束执行代码
                 this .timer1.Enabled =  false ;
             }
     
     
             protected  override  void  OnPause()
             {
                 //服务暂停执行代码
                 base .OnPause();
             }
             protected  override  void  OnContinue()
             {
                 //服务恢复执行代码
                 base .OnContinue();
             }
             protected  override  void  OnShutdown()
             {
                 //系统即将关闭执行代码
                 base .OnShutdown();
             }
         }
    展开全文
  • 我用timer写了一个定时任务能停止和重新启动的,使用@Autowired来注入CusTask timer使用end方法销毁后重启不了,但是如果去掉@Autowired注入 改成new CusTask();就可以实现停止与重新启动了,但是new CusTask();里面的@...
  • 定时任务里肯定可以查到 Timer ,关于 Timer 的介绍,有很多很详细的,我这里打算对该类进行演进,先从这个最简单的定时工具讲起,逐步实现定时任务的功能,周期性任务计划,多任务周期性计划。 起因 起因是因为我...
  • Java定时任务Timer和Quartz

    千次阅读 2018-09-12 10:13:23
    定时任务调度 ... 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务 ... Timer能完成一些简单的定时任务,能实现具体某个时间执行任务。只有一个后台执行定时任务。 Quartz能实现更复杂...
  • 虽然一个Timer可以运行多个定时任务,但是一个Timer是串行运行 Timer的使用禁区:1、对时效性要求比较较高的多任务并发作业 2、对复杂任务的调度 Timer的缺陷:1、管理并发的缺陷以及任务之间的协同缺陷(因为...
  • 使用Java timer定时器定时每天早上零点执行任务,写了一个监听器,但是如果当测试服务器和正式服务器都部署了项目之后,那么每天零点就会执行两次,想添加一个开关去实现如果测试服务器开的话,就给正式服务器关了,...
  • 使用Timer实现定时启动 并定时停止

    千次阅读 2018-08-03 10:13:33
    使用Timer实现定时启动 并定时停止 需求描述 针对每个省的数据发送短信 每个省发送短信的开始时间及结束时间是动态配置的 重点为 timer的取消任务方法 只会对未运行的任务取消 不会影响到正在运行的任务,而我们...
  • python的线程有一个类叫Timer可以,用来创建定时任务,但是它的问题是只能运行一次,如果要重复执行,则只能在任务中再调用一次timer,但这样就存在新的问题了,就是在主进程退出后,不能正常退出子线程。from ...
  •  //为定时器安排需要定时执行的任务,该任务就是前面创建的任务类TaskAvailableConnectNumber,并指定该任务每30分钟执行一次。  //设定每天推送的时间  Calendar cal=Calendar.getInstance();  cal.set...
  • C# Timer 定时任务

    2019-04-28 15:21:00
    C#中,Timer是一个定时器,它可以按照指定的时间间隔或者指定的时间执行一个事件。 指定时间间隔是指按特定的时间间隔,如每1分钟、每10分钟、每1个小时等执行指定事件; 指定时间是指每小时的第30分、每天10:30...
  • import java.util.Scanner; import java.util.Timer; import java.util.TimerTask; public class TimerTest { ... public static void main(String[] args) { ... Timer timer = new Timer(); timer.s.
  • Timer App 定时程序

    2013-09-01 16:55:29
    定时睡眠不能在关闭睡眠模式下使用 程序可以被任务管理器结束掉 第一次运行请在第一个界面选择“简体中文”作为语言 如今后需要修改语言 请删除“Settings ini”文件 系统要求: OS: Windows 2000 或 更高 ...
  • 在一个springboot项目中需要跑定时任务处理批数据时,突然有个Kill命令或者一个Ctrl+C的命令,此时我们需要当批数据处理完毕后才允许定时任务关闭,也就是当定时任务结束时才允许Kill命令生效。 启动类 @SpringBoot...
  • ​ 说到定时任务,我们常用的就是 crond 服务,但是我们不知道还有另外一种定时方式,那就是 systemd,我们常用 systemd 来管理我们的服务,但是我们却不知道,我们还可以通过 systemd 来设置定时任务。本文将记录下...
  • 参考文章:springboot自带定时器实现定时任务的开启关闭以及定时时间可以配置 一. 序言 最近项目需要用到定时任务,需要完成一个定时功能。经过了解,项目中目前实现定时任务,一般有三种选择: 一是用Java自带的...
  • java 定时任务Timer

    2018-07-12 16:08:38
    import java.text.SimpleDateFormat; import java.util.Timer;... * 定时任务 */ public class MyTimerTask extends TimerTask{ /** * 通过构造器注入 Timer对象,任务执行后调用Timer的c...
  • Hutool_定时任务

    2021-03-11 09:53:31
    定时任务在实际的工作当中,不可能全开全停,很多都是后台管理端有个简单的定时任务管理页面,超管可以对定时任务进行部分操作,例如:开启/关闭某个定时任务,一键开启/停止定时任务,说到这儿,前端要展示数据,...
  • Android中的定时任务一般有两种实现方式,一种是使用Java API中提供的 Timer 类,一种是使用Android的 Alarm 机制。 这两种方式在多数情况下都能实现类似的效果,但是 Timer 有一个明显的短板,就是不太是用于那些...
  • 上一篇博文《任务调度(一)——jdk自带的Timer》中,简单介绍了一下Timer,本文将分享一下如何动态修改Timer制定的计划。  有人问我Timer和Quartz框架的区别。那我就说一下我的理解。Timer毕竟是jdk自带的简易的...
  • Java多种定时任务

    2020-10-19 17:17:01
    文章目录定时任务1 Timer2 ScheduledExecutorService3 Spring Task3.1 基本使用4 执行时间配置4.1 cron表达式5 开/关定时任务 定时任务 1 Timer 这是java自带的java.util.Timer类,这个类允许你调度一个java.util....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,854
精华内容 6,341
热门标签
关键字:

timer关闭定时任务