当前位置:   article > 正文

JAVA定时任务 Timer TimerTask 笔记_java timertask

java timertask


前言

我并不喜欢干什么都动不动弄一大坨框架, 首先还是该掌握好自带的基础工具 , 然后是spring , 然后才是更大坨的工具

Java最基本的定时任务 : new一个线程并指定间隔和结束条件

	public static boolean 是否循环 = true;
	public static long 间隔时间毫秒 = 3000;
	public static void 干点什么方法() { System.out.println("世界你好");}
	public static void main(String...arguments) {
		new Thread(()->{
			while(是否循环) {
				干点什么方法();
				try{ Thread.sleep(间隔时间毫秒); }catch(Exception e) {System.err.println("sleep能有什么错");}
			}
		}).start();
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Timer + TimerTask 简单用法说明

例子:

  1. 实现 TimerTask的run方法, 明确要做什么
    可以继承实现, 也可用匿名内部类
  2. new 一个Timer
  3. 调用Timer实例的 schedule 或 scheduleAtFixedRate 方法
    将TimerTask放入Timer,并指定开始时间 和 间隔时间

延时三秒后执行一次:

		long 三秒后=3000;
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				
				System.out.println("要执行的代码");
				timer.cancel();
			}
		}, 三秒后);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

延时三秒后, 每秒执行一次, 用scheduleAtFixedRate方法:

		long 三秒后=3000 , 间隔1=1000;
		Timer timer = new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				
				System.out.println("要执行的代码");
				
			}
		}, 三秒后, 间隔1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

延时三秒后, 每秒执行一次, 用schedule方法:

		long 三秒后=3000 , 间隔1=1000;
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				
				System.out.println("要执行的代码");
				try {Thread.sleep(500);}catch(Exception e) {} //不会多加500毫秒
			}
		}, 三秒后, 间隔1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

java.util.Timer

基本原理

创建了一个任务队列 , 创建了一个执行线程
来自openJDK15的源码:

public class Timer {
    /**
     * The timer task queue.  This data structure is shared with the timer
     * thread.  The timer produces tasks, via its various schedule calls,
     * and the timer thread consumes, executing timer tasks as appropriate,
     * and removing them from the queue when they're obsolete.
     */
    private final TaskQueue queue = new TaskQueue();

    /**
     * The timer thread.
     */
    private final TimerThread thread = new TimerThread(queue);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Timer会创建一个线程执行TaskQueue中的TimerTask
一个Timer一个线程 , 所以 , 如果想多个不相干的任务互不干扰,就多new几个Timer,分别放入
相干的任务可以放入同一个Timer

主要方法

构造方法

  • public Timer()
  • public Timer(boolean isDaemon)
  • public Timer(String name)
  • public Timer(String name, boolean isDaemon)
Timer()
    public Timer() {
        this("Timer-" + serialNumber());
    }
  • 1
  • 2
  • 3
Timer(String name)
    public Timer(String name) {
        thread.setName(name);
        thread.start();
    }
  • 1
  • 2
  • 3
  • 4
Timer(boolean isDaemon)
    public Timer(boolean isDaemon) {
        this("Timer-" + serialNumber(), isDaemon);
    }
  • 1
  • 2
  • 3
Timer(String name, boolean isDaemon)
    public Timer(String name, boolean isDaemon) {
        thread.setName(name);
        thread.setDaemon(isDaemon);
        thread.start();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
构造方法的 isDaemon 参数

isDaemon 表示 是否是守护线程 , 默认设置参考 Thread类

    /* Whether or not the thread is a daemon thread. */
    private boolean daemon = false;
  • 1
  • 2

不指定的话, 默认false 不是守护线程

守护线程和默认线程的区别
  • 守护线程更像是跟班 , 主线程退出,就跟着退出了. 所以, 守护timer可能什么也没做程序就完了
  • 默认线程会一直等到自身执行完, 或一直在循环中, 所以, 默认timer排程后, 即便自己已执行完, 主线程也早执行完了, 但timer的线程依旧不会退出

schedule 和 scheduleAtFixedRate

schedule
  • public void schedule(TimerTask task, long delay) //延时执行一次
  • public void schedule(TimerTask task, Date time) //延时执行一次
  • public void schedule(TimerTask task, long delay, long period) //延时且循环
  • public void schedule(TimerTask task, Date firstTime, long period) //延时且循环
scheduleAtFixedRate
  • public void scheduleAtFixedRate(TimerTask task, long delay, long period) //延时且循环
  • public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) //延时且循环
比较 schedule方法 和 scheduleAtFixedRate方法 的区别
  • schedule(TimerTask task, long delay, long period) openJDK15
public void schedule(TimerTask task, long delay, long period) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, System.currentTimeMillis()+delay, -period);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • scheduleAtFixedRate(TimerTask task, long delay, long period) openJDK15
 public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, System.currentTimeMillis()+delay, period);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

它们都调用sched方法
不同在于, 传入的 period 一个为负 , 一个为正

  • private void sched(TimerTask task, long time, long period)
    /**
     * Schedule the specified timer task for execution at the specified
     * time with the specified period, in milliseconds.  If period is
     * positive, the task is scheduled for repeated execution; if period is
     * zero, the task is scheduled for one-time execution. Time is specified
     * in Date.getTime() format.  This method checks timer state, task state,
     * and initial execution time, but not period.
     *
 Schedule(排程)指定的timerTask以指定的时间在指定的period(以毫秒为单位)执行。 
 如果period为正,则计划将任务安排为重复执行;
 如果period为零,则task只执行一次。 
 时间以Date.getTime()格式指定。 
 此方法检查timer状态,task状态和初始执行时间,但不检查period(周期)。 
     */
    private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");

        // Constrain value of period sufficiently to prevent numeric
        // overflow while still being effectively infinitely large.
        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;

        synchronized(queue) {
            if (!thread.newTasksMayBeScheduled)
                throw new IllegalStateException("Timer already cancelled.");

            synchronized(task.lock) {
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
                task.nextExecutionTime = time;
                task.period = period;
                task.state = TimerTask.SCHEDULED;
            }

            queue.add(task);
            if (queue.getMin() == task)
                queue.notify();
        }
    }
  • 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

sched源码

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/600447
推荐阅读
相关标签