Java多线程基础(二)定时器类:Timer类和TimerTask类

Java多线程基础(二)定时器类:Timer类和TimerTask类

Timer类和TimerTask类是jdk实现定时器功能的早期方法,jdk1.5以前就支持Timer类和TimerTask类。JDK1.5之后引入了新的机制,将在后续博文中研究。

1 指定时间间隔后执行任务

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

public class TraditionalTimerTest {

    public static void main(String[] args) {

        // 启动定时器线程,并在10000毫秒后执行TimerTask实例的run方法
        new Timer().schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println("bombing!");

            }
        }, 10000);

        while(true) {
            System.out.println("时钟时间:" + new Date().getSeconds());
            try {
                Thread.sleep(1000);// 主线程每隔1秒钟,打印当前时钟时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

调用的主要java API的源代码及java doc:

    public void schedule(TimerTask task, long delay) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        sched(task, System.currentTimeMillis()+delay, 0);
    }

Schedules the specified task for execution after the specified delay.

安排在指定延迟后执行指定的任务。

Parameters:

task - task to be scheduled.

delay - delay in milliseconds before task is to be executed.

Throws:

IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.

IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.

NullPointerException - if task is null

2 指定时间间隔后循环执行任务

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

public class TraditionalTimerTest {

    public static void main(String[] args) {
        // 启动定时器线程,并在10000毫秒后开始,每隔3000毫秒执行一次定时任务
        new Timer().schedule(new TimerTask() {// 定时任务

            @Override
            public void run() {
                System.out.println("bombing!");

            }
        }, 10000, 3000);

        while(true) {
            System.out.println("时钟时间:" + new Date().getSeconds());
            try {
                Thread.sleep(1000);// 主线程每隔1秒钟,打印当前时钟时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

调用的主要java API的源代码及java doc:

    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);
    }

Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals separated by the specified period.

安排指定的任务从指定的延迟后开始进行重复的 固定延迟执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。

In fixed-delay execution, each execution is scheduled relative to the actual execution time of the previous execution. If an execution is delayed for any reason (such as garbage collection or other background activity), subsequent executions will be delayed as well. In the long run, the frequency of execution will generally be slightly lower than the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).

在固定延迟执行中,根据前一次执行的实际执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则后续执行也将被延迟。从长期来看,执行的频率一般要稍慢于指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。

Fixed-delay execution is appropriate for recurring activities that require “smoothness.” In other words, it is appropriate for activities where it is more important to keep the frequency accurate in the short run than in the long run. This includes most animation tasks, such as blinking a cursor at regular intervals. It also includes tasks wherein regular activity is performed in response to human input, such as automatically repeating a character as long as a key is held down.

固定延迟执行适用于那些需要“平稳”运行的重复活动。换句话说,它适用于在短期运行中保持频率准确要比在长期运行中更为重要的活动。这包括大多数动画任务,如以固定时间间隔闪烁的光标。这还包括为响应人机输入所执行的固定活动,如在按住键时自动重复输入字符。

Parameters:

task - task to be scheduled.

delay - delay in milliseconds before task is to be executed.

period - time in milliseconds between successive task executions.

Throws:

IllegalArgumentException - if delay < 0, or delay + System.currentTimeMillis() < 0, or period <= 0

IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.

NullPointerException - if task is null

3 更灵活地间隔

每隔2秒,4秒,2秒,4秒,…,循环执行任务。

方法1 定义一个TimerTask类

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

public class TraditionalTimerTest {

    static int count = 0;

    public static void main(String[] args) {

        class MyTimerTask extends TimerTask {

            @Override
            public void run() {
                count = (count+1)%2;// 用于定制不同的间隔时间
                System.out.println("bombing!");
                new Timer().schedule(
                        new MyTimerTask(),//递归地实例化新的定时任务
                        2000 + 2000 * count);
            }
        }

        new Timer().schedule(new MyTimerTask(), 2000);
        while(true) {
            System.out.println("时钟时间:" + new Date().getSeconds());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

方法2 定义两个/多个TimerTask类

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

public class TraditionalTimerTest {

    public static void main(String[] args) {

        new Timer().schedule(new MyTimerTask1(), 2000);

        while(true) {
            System.out.println("时钟时间:" + new Date().getSeconds());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
class MyTimerTask1 extends TimerTask {

    @Override
    public void run() {
        System.out.println("Task1");
        new Timer().schedule(new MyTimerTask2(), 2000);// 启动定时任务2
    }

}
class MyTimerTask2 extends TimerTask {

    @Override
    public void run() {
        System.out.println("Task2");
        new Timer().schedule(new MyTimerTask1(), 4000);// 启动定时任务1
    }

}

4 Timer的其他常用API

返回值 方法签名
void schedule(TimerTask task, Date time)
Schedules the specified task for execution at the specified time.
安排在指定的时间执行指定的任务。如果此时间已过去,则安排立即执行该任务。
void schedule(TimerTask task, Date firstTime, long period)
Schedules the specified task for repeated fixed-delay execution, beginning at the specified time.
安排指定的任务在指定的时间开始进行重复的 固定延迟执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。

在固定延迟执行中,根据前一次执行的实际执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则后续执行也将被延迟。在长期运行中,执行的频率一般要稍慢于指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。

固定延迟执行适用于那些需要“平稳”运行的重复执行活动。换句话说,它适用于在短期运行中保持频率准确要比在长期运行中更为重要的活动。这包括大多数动画任务,如以固定时间间隔闪烁的光标。这还包括为响应人类活动所执行的固定活动,如在按住键时自动重复输入字符。

void schedule(TimerTask task, long delay)
Schedules the specified task for execution after the specified delay.
安排在指定延迟后执行指定的任务。
void schedule(TimerTask task, long delay, long period)
Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay.
安排指定的任务从指定的延迟后开始进行重复的 固定延迟执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。

在固定延迟执行中,根据前一次执行的实际执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则后续执行也将被延迟。从长期来看,执行的频率一般要稍慢于指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。

固定延迟执行适用于那些需要“平稳”运行的重复活动。换句话说,它适用于在短期运行中保持频率准确要比在长期运行中更为重要的活动。这包括大多数动画任务,如以固定时间间隔闪烁的光标。这还包括为响应人类活动所执行的固定活动,如在按住键时自动重复输入字符。

void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
Schedules the specified task for repeated fixed-rate execution, beginning at the specified time.
安排指定的任务在指定的时间开始进行重复的 固定速率执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。

在固定速率执行中,相对于已安排的初始执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则将快速连续地出现两次或更多次执行,从而使后续执行能够赶上来。从长远来看,执行的频率将正好是指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。

固定速率执行适用于那些对绝对 时间敏感的重复执行活动,如每小时准点打钟报时,或者在每天的特定时间运行已安排的维护活动。它还适用于那些完成固定次数执行的总计时间很重要的重复活动,如倒计时的计时器,每秒钟滴答一次,共 10 秒钟。最后,固定速率执行适用于安排多次重复执行的计时器任务,这些任务相互之间必须保持同步。

void scheduleAtFixedRate(TimerTask task, long delay, long period)
Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay.
安排指定的任务在指定的延迟后开始进行重复的 固定速率执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。

在固定速率执行中,根据已安排的初始执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则将快速连续地出现两次或更多的执行,从而使后续执行能够“追赶上来”。从长远来看,执行的频率将正好是指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。

固定速率执行适用于那些对绝对 时间敏感的重复执行活动,如每小时准点打钟报时,或者在每天的特定时间运行已安排的维护活动。它还适用于那些完成固定次数执行的总计时间很重要的重复活动,如倒计时的计时器,每秒钟滴答一次,共 10 秒钟。最后,固定速率执行适用于安排多个重复执行的计时器任务,这些任务相互之间必须保持同步。

更多详细API信息可以参考Java SE API:

英文API:http://docs.oracle.com/javase/6/docs/api/index.html

中文API:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

更复杂的定时器可以使用quartz库:http://www.quartz-scheduler.org/

时间: 2024-10-27 17:03:57

Java多线程基础(二)定时器类:Timer类和TimerTask类的相关文章

Java多线程基础(二)

信号量Semaphore,类似于锁的功能,用于多线程中对一组资源的控制. acquire方法用于尝试获取一个资源,未获取前将一直等待.release用于释放一个资源,release的前提是已经获得了一个资源. package multiThread; import java.util.concurrent.Semaphore; public class SemaphoreTest { public static void main(String [ ] args) { int N = 8; //

[转]Java多线程干货系列—(一)Java多线程基础

Java多线程干货系列—(一)Java多线程基础 字数7618 阅读1875 评论21 喜欢86 前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们来说极其重要,下面跟我一起开启本次的学习之旅吧. 正文 线程与进程 1 线程:进程中负责程序执行的执行单元线程本身依靠程序进行运行线程是程序中的顺序控制流,只能使用分配给程序的资源和环境 2 进程:执行中的程序一个进程至少包含一个线程 3 单线程:程序中只存在一个线程,实际上主方法就是一个主线程 4

Java多线程基础

1. 前言 这篇文章,是对Java多线程编程的基础性介绍. 文章将介绍Java语言为支持多线程编程提供的一些特性.通过这篇文章,您将了解到如何通过Java语言创建一个线程,如何通过内置的锁来实现线程间的同步,如何在线程间进行通信以及线程的中断机制. 2. 什么是线程 线程是操作系统调度的最小单位,在一个进程中,一般至少有一个线程在运行.一个进程中包含的多个线程,在多核处理器中,操作系统可以将多个线程调度到不同的CPU核心上运行,多个线程可以并行运行. 在同一个进程中的多个线程,共享同一个进程空间

Java多线程编程5--定时器Timer的使用

定时/计划功能在移动开发领域使用较多,比如Android技术.定时计划任务功能在Java中主要使用的就是Timer对象,它在内部使用多线程的方式进行处理,所以它和线程技术还是有非常大的关联的. 在JDK库中Timer类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务. Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类 执行计划任务的代码要放人TimerTask的子类中,因为TimerTask是一个抽象类. schedule (TimerTask task

java多线程基础知识

1.ThrTest.java 继承Thread类方式 public class ThrTest extends Thread { private String name; public ThrTest() { } public ThrTest(String name) { this.name = name; } public void run() { for (int i = 0; i < 5; i++) { System.out.println(name + "运行 " + i

黑马程序员——java多线程基础知识1

多线程 进程是一个正在执行的程序. cpu在同时执行这些程序,其实是跳跃式的,做快速的切换,时间很短.一个进程可能存在多条路径.迅雷的多路径.每一个进行执行都有一个执行顺序,该顺序是一个执行路径,或这叫一个控制单元.每一个进程至少有一个线程,线程就是进程中的一个独立的控制单元,线程控制进程的执行.jvm启动的时候会有一个进程就叫做java,exe,该进程中至少有一个线程在控制Java程序的执行 ,而且该线程的执行代码在 主函数中.该线程称为主线程.虚拟机至少也有两个线程,一个主线程执行,另一个负

黑马程序员——Java多线程基础知识2

多线程协同 线程间的通讯:我们对资源的操作动作不同,比如说两个卡车一个拉煤一个装煤.但是他们共享了一个资源. 怎么样把这个资源拿出来?怎样把车装满?这个资源当然是一个类,他里面的组成元素就是对象!!现在我们就要有操作对象的思想了,我用对象把这车装满,现在一车装一个对象. 等待唤醒机制: 用的不是sleep是wait.flag标记,这是两人沟通的方式.其实每个标记就要做一次等待或者notify,判断wait,改值notify.线程池.notify唤醒里面的线程,按顺序唤醒.wait和notify必

Java多线程基础总结

背景 Java采用多线程方式实现并行计算,当然并行计算也可以采用多进程方式实现,但是进程切换耗费比较高.而且进程间是隔离的,进程间通信机制比较麻烦,最后JVM本身在操作系统中就一个进程,由它再启动一个进程不太合适,所以Java采用多线程方式实现并行计算. Java从诞生之初,多线程就围绕的是Runnable接口和Thread类展开的.它的底层采用的是c的p线程方式,而且由于多线程的复杂性,p线程的很多概念知识被延伸到了Java层面,这对Java开发者来说算是一个不幸的消息.但是由于多线程的复杂性

Java多线程(二)、线程的生命周期和状态控制(转)

Java多线程(二).线程的生命周期和状态控制 分类: javaSE综合知识点 2012-09-10 16:11 15937人阅读 评论(3) 收藏 举报 一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable). 注意:不能对已经启动的线程再次调用start()方法,否则会出现java.lang.IllegalThreadSt