多线程十 Timer

简介: 多线程十 Timer

定时/计算在java中主要使用的是Timer对象,他的内部依然是采用多线程方式进行处理


它有四个构造方法#



方法名 作用
Timer() 空参
Timer(String name) 指定名字
Timer(boolean isDaemon) 指定为守护线程
Timer(String name,boolean isDaman) 指定名字,指定为守护线程


Timer类的主要作用就是设置计划任务,但是封装任务的类确是TimerTask,TimerTask实现了Runable接口,因此我们要做的也就是重写run方法,定义我们的任务


  • 简单使用


public class demo01 extends TimerTask {
@Override
public void run() {
    System.out.println("计划执行了,  "+new Date());
}
public static void main(String[] args) {
    System.out.println("当前时间  "+ new Date());
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.SECOND,5);
    Date time = calendar.getTime();
    demo01 task = new demo01();
    Timer timer = new Timer();
    timer.schedule(task,time);
    System.out.println("主线程结束了...");
}
}


程序执行完了,但是进程仍然没有被撤销,呈红色状态,那是因为每创建一个Timer对象,就是启动一条线程,并且这条线程不是守护线程,会一直执行下去


常用的几个Timer对象的API#


1. 安排在指定的时间执行指定的任务,如果时间过去了,立即执行#


void schedule(TimerTask task,Date time)


一个Timer对象,可以拥有多个TimerTask,而TimerTask是以队列的方法,一个一个顺序执行,这也就可能导致执行的时间和预期的时间不一样,因为前面的任务执行的时间可能比较长,那么后面的任务也就被延后了


2. 在指定的日期到达之后,按照指定的时间间隔,执行一次某任务#


schedule(TimerTask task , Date firstTime,Long period)


注意点:

  1. firstTime晚于当前时间,计划未来
  2. firstTime早于当前时间,计划立即执行
  3. 任务依然可能被延迟


3, 以当前时间为准,在此时间基础上延迟指定的时间毫秒数执行一次TimerTask任务#


schedule(TimerTask task, Long delay)


4 .当前的时间为参考,在此时间基础上延迟指定的毫秒数,再以某一个时间间隔,无限次执行某一任务#


schedule(TimerTask task,Long delay,Long period)


5. 测试schedule&scheduleAtFixedRate几种情况#


不延迟 描述
Date类型 下一次执行任务的时间,都是上一次任务开始的时间+period
Long类型 第一次任务执行的时间是任务开始的时间+delay,接下来执行任务的时间是上一次任务开始的时间+priod
延迟 描述
Date类型 下一次执行任务的时间,都是上一次任务结束的时间+period
Long类型 下一次执行任务的时间是上一次任务结束的时间+priod


6. 追赶性#


举个例子什么是追赶性,假如说,程序运行到A行代码时,时间是t1,程序继续往下执行,遇到了B行代码,我们希望,B在A前10秒执行给定的任务,可是按照我们的顺序,A已经执行了,那么实现我们的要求就用到了scheduleAtFixedRate的追赶性

示例代码:


/*
* schedule的追赶性
* */
public class demo03 extends TimerTask {
    @Override
    public void run() {
        System.out.println("任务开始的时间"+new Date());
        System.out.println("任务结束的时间"+new Date());
    }
    public static void main(String[] args) {
        System.out.println("现在执行的时间+"+new Date());
        demo03 task = new demo03();
        Calendar instance = Calendar.getInstance();
           instance.set(Calendar.SECOND,instance.get((Calendar.SECOND)-10));
        Date time = instance.getTime();
        System.out.println("计划执行的时间"+ time);
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(task,time,2000);
    }
}


结果:


现在执行的时间+Sat Feb 16 07:17:14 CST 2019
计划执行的时间Sat Feb 16 07:17:07 CST 2019
任务开始的时间Sat Feb 16 07:17:14 CST 2019
任务结束的时间Sat Feb 16 07:17:14 CST 2019
任务开始的时间Sat Feb 16 07:17:14 CST 2019
任务结束的时间Sat Feb 16 07:17:14 CST 2019
任务开始的时间Sat Feb 16 07:17:14 CST 2019
任务结束的时间Sat Feb 16 07:17:14 CST 2019
任务开始的时间Sat Feb 16 07:17:14 CST 2019
任务结束的时间Sat Feb 16 07:17:14 CST 2019
任务开始的时间Sat Feb 16 07:17:15 CST 2019
任务结束的时间Sat Feb 16 07:17:15 CST 2019
任务开始的时间Sat Feb 16 07:17:17 CST 2019
任务结束的时间Sat Feb 16 07:17:17 CST 2019
任务开始的时间Sat Feb 16 07:17:19 CST 2019
任务结束的时间Sat Feb 16 07:17:19 CST 2019
任务开始的时间Sat Feb 16 07:17:21 CST 2019
任务结束的时间Sat Feb 16 07:17:21 CST 2019
任务开始的时间Sat Feb 16 07:17:23 CST 2019
...


TimerTaskTimer的cancel方法


  • TimerTask的cancel()自然由TimerTask对象调用,它本身是任务队列中的一个任务,作用是把自身从任务队列中进行清除
  • Timer的cancel()方法**把整个任务队列清除


Timer的cancel的注意事项#


public class demo02 extends TimerTask {
    private int i;
    public demo02(int i) {
        this.i = i;
    }
    @Override
    public void run() {
        System.out.println("任务被第"+i+"次执行,没有被取消");
    }
    public static void main(String[] args) {
        int i=0;
        Calendar calendar = Calendar.getInstance();
        Date time = calendar.getTime();
        while(true){
            i++;
            Timer timer = new Timer();
            timer.schedule(new demo02(i),time);
            timer.cancel();
        }
    }


运行结果


任务被第32412次执行,没有被取消


原因是Timer类中的cancel方法,有时抢不到任务队列的锁,而让TimerTask类中的任务正常执行


参考书籍<<java多线程编程核心技术>>高洪岩著

相关文章
|
8月前
多线程(初阶八:计时器Timer)
多线程(初阶八:计时器Timer)
119 0
|
3月前
|
安全 Java
【多线程-从零开始-拾】Timer-定时器
【多线程-从零开始-拾】Timer-定时器
43 0
|
8月前
|
Java
【Java多线程】定时器Timer
【Java多线程】定时器Timer
60 0
【Java多线程】定时器Timer
|
druid 关系型数据库 MySQL
高并发下 MySQL Statement Cancellation Timer 的线程数暴涨
高并发下 MySQL Statement Cancellation Timer 的线程数暴涨
【JavaEE】多线程之定时器(Timer)
【JavaEE】多线程之定时器(Timer)
|
安全 Java
【Java|多线程与高并发】定时器(Timer)详解
在Java中,定时器Timer类是用于执行定时任务的工具类。它允许你安排一个任务在未来的某个时间点执行,或者以固定的时间间隔重复执行。
|
Java 测试技术
在多线程中自定义实现定时器(Timer)
在多线程中自定义实现定时器(Timer)
【Java多线程】定时器Timer
在任务的执行时间未到之前,可能判断次数很多,比较耗费CPU,而且没有必要一值判断,只需在一定时间内进行判断执行时间到没到即可,所以在还没有到执行时间时,使用wait(时间)来让该线程进行等待,在创建任务时唤醒等待即可,因为新的任务可能需要在刚才等待执行任务之前执行,也就是新创建的任务执行时间已经到了,所以要使用notify唤醒执行任务的线程继续进行判断时间是否执行,而且这个原因也是使用wait不使用sleep的原因,如果使用sleep,在新创建任务的执行时间在sleep等待结束时间之前,等待的线程没有办法唤醒,也就不能执行时间到了的任务
【Java多线程】定时器Timer
|
消息中间件 算法 Java
面试官:知道时间轮算法吗?在Netty和Kafka中如何应用的?为什么不用Timer、延时线程池?(下)
面试官:知道时间轮算法吗?在Netty和Kafka中如何应用的?为什么不用Timer、延时线程池?(下)
面试官:知道时间轮算法吗?在Netty和Kafka中如何应用的?为什么不用Timer、延时线程池?(下)