zoukankan      html  css  js  c++  java
  • Java线程之Timer

    在这里插入图片描述

    简述

    java.util.Timer是一个定时器,用来调度线程在某个时间执行。在初始化Timer时,开启一个线程循环提取TaskQueue任务数组中的任务,

    如果任务数组为空,线程等待直到添加任务;

    当添加任务时,唤醒线程,提取数组中标记为1的任务,

    如果该任务状态为CANCELLED,则从数组中删除任务,继续循环提取任务

    TimerTask

    TimerTask是一个抽象类,它实现了Runnable接口,我们需要继承TimerTask来创建自己的任务类,然后可以使用Timer去调度我们自定义的任务类。

    Timer是线程安全的,多个线程可以共享一个Timer对象不需要额外加锁。Timer使用java.util.TaskQueue 来存储添加的任务,在任何时间只有一个线程去执行TimerTask,例如,如果您正在创建一个计时器,每10秒运行一次,但是单线程执行需要20秒,计时器对象将继续向队列中添加任务,当一个线程完成后,它将通知队列,另一个线程将开始执行。

    Timer对象使用Object对象的 wait 和 notify方法去调度TimerTask去执行的

    事例

    package com.lkf.mulithread;
    
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class MyTimerTask extends TimerTask {
    
        @Override
        public void run() {
            
            System.out.println("Timer task started at:"+new Date());
            completeTask();
            System.out.println("Timer task finished at:"+new Date());
        }
    
        private void completeTask() {
            try {
                //任务完成需要20秒
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String args[]){
            TimerTask timerTask = new MyTimerTask();
            //running timer task as daemon thread
            Timer timer = new Timer(true);
            //每个10秒调度一次
            timer.scheduleAtFixedRate(timerTask, 0, 10*1000);
            System.out.println("TimerTask started");
            //cancel after sometime
            try {
                Thread.sleep(120000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            timer.cancel();
            System.out.println("TimerTask cancelled");
            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    
    }
    
    

    定时器每隔10秒调度一次任务,一个任务执行时间需要20秒

    输出结果:

    TimerTask started
    Timer task started at:Sun Mar 25 13:20:35 CST 2018
    Timer task finished at:Sun Mar 25 13:20:55 CST 2018
    Timer task started at:Sun Mar 25 13:20:55 CST 2018
    Timer task finished at:Sun Mar 25 13:21:15 CST 2018
    Timer task started at:Sun Mar 25 13:21:15 CST 2018
    Timer task finished at:Sun Mar 25 13:21:35 CST 2018
    Timer task started at:Sun Mar 25 13:21:35 CST 2018
    Timer task finished at:Sun Mar 25 13:21:55 CST 2018
    Timer task started at:Sun Mar 25 13:21:55 CST 2018
    Timer task finished at:Sun Mar 25 13:22:15 CST 2018
    Timer task started at:Sun Mar 25 13:22:15 CST 2018
    TimerTask cancelled
    Timer task finished at:Sun Mar 25 13:22:35 CST 2018
    

    由输出结果可以确认,定时器将等待任务完成,一旦完成,它将再次从队列开始下一个任务

    总结

    Timer定时器可以作为守护线程对任务进行调度,计时器cancel()方法用于终止计时器并丢弃任何设置好的任务,但是,它不会干扰当前执行的任务,会让它完成。

    当Timer定时器作为守护线程,一旦我们调用取消定时器方法,等所有正在执行的用户线程执行完毕,定时器线程将会被终止

    定时器类包含多个schedule()方法,用于安排在给定日期或延迟之后运行一次任务,有几个scheduleAtFixedRate()方法在一定时间间隔内运行任务

    当我们使用Timer作为定时任务调度器时,要确保调度时间间隔不大于任务运行时间,否则,任务队列大小将持续增长,最终任务将始终执行

    另外当多线程并行处理定时任务时,Timer运行多个TimerTask时,只要其中一个任务抛出异常,那么所有的任务都将被终止

    翻译自:https://www.journaldev.com/1050/java-timer-timertask-example?utm_source=website&utm_medium=sidebar&utm_campaign=Core-Java-Sidebar-Widget

  • 相关阅读:
    asp.net ajax传递Json给aspx.cs后台 webmethod方法传递json
    新手 Redis 配置笔记(windows),附下载地址
    在 LINQ to Entities 查询中无法构造实体或复杂类型
    WebApi 4.0 默认方式不支持HttpGet 请求
    jQuery .Ajax Error Handling Function
    My97DatePicker 与 某个CSS冲突 ,导致无法显示
    基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系
    使用Autofac部署IIS6.0时未能加载文件或程序集“System.Core, Version=2.0.5.0...“
    Could not load file or assembly 'System.Core, Version=2.0.5.0 和autofac冲突的问题
    线程间操作无效: 从不是创建控件“textBox2”的线程访问它
  • 原文地址:https://www.cnblogs.com/liukaifeng/p/10052658.html
Copyright © 2011-2022 走看看