java中Timer和Timertask的关系

本文详细解析了Java中的Timer和TimerTask之间的关系,包括它们的作用、如何创建和使用、线程处理、终止机制以及注意事项。特别提到使用ScheduledThreadPoolExecutor替代Timer的建议。
摘要由CSDN通过智能技术生成

一 time和timertask的关系

1.1 timer和timertask关系

1.Timer来讲就是一个调度器,而TimerTask呢只是一个实现了run方法的一个类;

2.Timer和TimerTask成对出现,Timer是定时器,TimerTask是定时任务。换句话说,定时任务TimerTask是给定时器Timer执行的具体任务。TimerTask实现Runnable接口的run方法。

Java的定时器Timer和定时任务TimerTask应用以及原理简析_java timertask-CSDN博客

3.每一个Timer仅对应唯一一个线程。Timer不保证任务执行的十分精确。
Timer类的线程安全的。

4.一个Timer可以调度任意多个TimerTask,所有任务都存储在一个队列中顺序执行,如果需要多个TimerTask并发执行,则需要创建两个多个Timer。

一个Timer可以执行多个TimerTask,但一个TimerTask只能被一个Timer使用(这和schedule中校验TimerTask的状态有关,TimerTask的生命周期(由不同的状态确定))。

简单的说Timer中有两个核心部分:

TimerThread是时间线程,控制TaskQueue中TimerTask的执行;
TaskQueue是一个工具类,管理TimerTask数组

1.2 timer的api

 1.无参构造方法,简单通过Tiemer为前缀构造一个线程名称

2.有参构造方法,传入了是否为后台线程,后台线程当且仅当进程结束时,自动注销掉。

1.3 终止Timer线程

默认情况下,创建的timer线程会一直执行,主要有下面四种方式来终止timer线程:

1) 调用Timer.cancle()方法。可以在程序任何地方调用,甚至在TimerTask中的run方法中调用;

2) 创建Timer时定义位daemon守护线程,使用new Timer(true)语句;

 3) 设置Timer对象为null,其会自动终止;????有待考证

 4) 调用System.exit方法,整个程序终止。

1.4 timer注意事项

1) Timer线程不会捕获异常,所以TimerTask抛出的未检查的异常会终止timer线程。如果Timer线程中存在多个计划任务,其中一个计划任务抛出未检查的异常,则会引起整个Timer线程结束,从而导致其他计划任务无法得到继续执行。  

 2) Timer线程时基于绝对时间(如:2023/02/14 16:06:00),因此计划任务对系统的时间的改变是敏感的。

 3) Timer是单线程,如果某个任务很耗时,可能会影响其他计划任务的执行。

   因此,JDK1.5以上建议使用ScheduledThreadPoolExecutor来代替Timer执行计划任务。

二 操作案例

2.1 一个Timer执行多个Task,堵塞现象

package com.ljf.lockdemo.task.timerdemo;

import java.util.Timer;
import java.util.TimerTask;

/**
 * @ClassName: TestDemo2
 * @Description: TODO
 * @Author: admin
 * @Date: 2024/03/02 11:30:06 
 * @Version: V1.0
 **/
public class TestDemo2 {
    public static void main(String[] args) {
        TimerTask task1=new TimerTask() {
            @Override
            public void run() {
                String name = Thread.currentThread().getName();
                System.out.println("[当前线程是:"+name+",执行定时任务1:"+System.currentTimeMillis()+"]");
            }
        };

        TimerTask task2=new TimerTask() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String name = Thread.currentThread().getName();
                System.out.println("[当前线程是:"+name+",执行定时任务2:"+System.currentTimeMillis()+"]");
            }
        };


        Timer timer=new Timer();
        timer.schedule(task2,10000);
        timer.schedule(task1,100,3000);

    }
}

结果:

2.2 异常现象

1.现象操作,在timetask2中,模拟一个除以0的算术异常。

强调:在执行任何一个任务的run方法时,一旦run抛出了异常,Timer线程就会退出,从而所有定时任务都会被取消。如果希望各个定时任务互不干扰,一定要在run方法内捕获所有异常。

这里catch的异常为:integerrupteException 

改成Exception e 如图

 3.启动两个timer

2.3  总结

1个timer没有cancel掉,使用的一直是一个线程id;1个timer关闭后,再每次new后,使用的线程id都不相同。

2.在1个timer中,开启两个timetask;这个两个timertask串行执行,单线程;使用的线程id是相同的。

 

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值