文档章节

Java中使用Timer和TimerTask实现多线程

Nori
 Nori
发布于 2016/03/16 09:13
字数 944
阅读 135
收藏 4

Timer是一种线程设施,用于安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行,可以看成一个定时器,可以调度TimerTask。TimerTask是一个抽象类,实现了Runnable接口,所以具备了多线程的能力。

测试代码:

import java.util.TimerTask;
public class OneTask extends TimerTask{
    private int id;
    public OneTask(int id){
        this.id = id;
    }
    @Override
    public void run() {
        System.out.println("线程"+ id +":  正在 执行。。"); 
    }   
}

然后主程序代码为:

import java.util.Date;
import java.util.Timer;
public class Test1 {
    public static void main(String[] args) {
        Timer timer = new Timer(); 
        timer.schedule(new OneTask(1), 5000);
        OneTask secondTask= new OneTask(2);
        timer.schedule(secondTask, 1000, 3000);
        Date date = new Date();
        timer.schedule(new OneTask(3),new Date(date.getTime()+1000));
        System.out.println("end in main thread...");
    }
}


Timer里面有4个schedule重载函数。而且还有两个scheduleAtFixedRate:

void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

安排指定的任务在指定的时间开始进行重复的固定速率执行。

void scheduleAtFixedRate(TimerTask task, long delay, long period)

安排指定的任务在指定的延迟后开始进行重复的固定速率执行。


使用scheduleAtFixedRate的话, Timer会尽量的让任务在一个固定的频率下运行。例如:在上面的例子中,让secondTask在1秒钟后,每3秒钟执行一次,但是因为java不是实时的,所以,我们在上个程序中表达的原义并不能够严格执行,例如有时可能资源调度紧张4秒以后才执行下一次,有时候又3.5秒执行。如果我们调用的是scheduleAtFixedRate,那么Timer会尽量让你的secondTask执行的频率保持在3秒一次。运行上面的程序,假设使用的是scheduleAtFixedRate,那么下面的场景就是可能的:1秒钟后,secondTask执行一次,因为系统繁忙,之后的3.5秒后secondTask才得以执行第二次,然后Timer记下了这个延迟,并尝试在下一个任务的时候弥补这个延迟,那么2.5秒后,secondTask 将执行的三次。“以固定的频率而不是固定的延迟时间去执行一个任务”就是这个意思。

Timer终止的问题:

默认情况下,只要一个程序的timer线程在运行,那么这个程序就会保持运行。可以通过以下3种方法终止一个timer线程:

(1)调用timer的cancle方法。你可以从程序的任何地方调用此方法,甚至在一个timer task的run方法里;

(2)让timer线程成为一个daemon线程(可以在创建timer时使用new Timer(true)达到这个目地),这样当程序只有daemon线程的时候,它就会自动终止运行; 

(3)调用System.exit方法,使整个程序(所有线程)终止。

TimerTask也有cancel方法。

上面所说的“只要一个程序的timer线程在运行,那么这个程序就会保持运行”。那么反过来,如果Timer里的所有TimerTask都执行完了,整个程序会退出吗,经测试答案是否定的,例如上面的测试代码,如果只加第一个TimerTask在Timer中执行:

timer.schedule(new OneTask(1), 5000);// 5秒后启动任务

那么5秒以后,其实整个程序还是没有退出,Timer会等待垃圾回收的时候被回收掉然后程序会得以退出,但是多长时间呢?

在TimerTask的run函数执行完以后加上System.gc();就可以了。


本文转载自:http://www.bdqn.cn/news/201305/9303.shtml

Nori
粉丝 9
博文 43
码字总数 7850
作品 0
淄博
高级程序员
私信 提问
Java线程(五):Timer和TimerTask

Timer和TimerTask可以做为实现线程的第三种方式,前两中方式分别是继承自Thread类和实现Runnable接口。 Timer是一种线程设施,用于安排以后在后台线程中执行的任务。可安排任务执行一次,或者...

天下杰论
2013/12/31
146
0
-1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方...

noteless
2018/07/03
0
0
Android中实现定时器的四种方式

Android中实现定时器的四种方式 第一种方式利用Timer和TimerTask 1、继承关系 java.util.Timer 基本方法 schedule 例如: [java] view plaincopyprint? schedule方法有三个参数 第一个参数就...

Yao--靠自己
2018/05/16
150
0
JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m366917/article/details/52714313 JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费...

Aduroidpc
2016/10/01
0
0
Java中定时任务的实现:Timer与ScheduledExecutorService的不同

前言 在做后台任务的时候经常需要实现各种各种的定时的,周期性的任务。比如每隔一段时间更新一下缓存之类的。通常周期性的任务都可以使用如下方式实现: class MyTimerThread extends Thre...

wf78728381
2017/10/18
26
0

没有更多内容

加载失败,请刷新页面

加载更多

3_数组

3_数组

行者终成事
29分钟前
3
0
经典系统设计面试题解析:如何设计TinyURL(二)

原文链接:https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
今天
7
0
使用logstash同步MySQL数据到ES

概述   在生成业务常有将MySQL数据同步到ES的需求,如果需要很高的定制化,往往需要开发同步程序用于处理数据。但没有特殊业务需求,官方提供的logstash就很有优势了。   在使用logstas...

zxiaofan666
今天
10
0
X-MSG-IM-分布式信令跟踪能力

经过一周多的鏖战, X-MSG-IM的分布式信令跟踪能力已基本具备, 特点是: 实时. 只有要RX/TX就会实时产生信令跟踪事件, 先入kafka, 再入influxdb待查. 同时提供实时sub/pub接口. 完备. 可以完整...

dev5
今天
7
0
OpenJDK之CyclicBarrier

OpenJDK8,本人看的是openJDK。以前就看过,只是经常忘记,所以记录下 图1 CyclicBarrier是Doug Lea在JDK1.5中引入的,作用就不详细描述了,主要有如下俩个方法使用: await()方法,如果当前线...

克虏伯
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部