Java 计时器 Timer 与 定时任务 TimeTask

目录

java.util.Timer.Timer 概述

java.util.Timer.TimerTask 概述

鼠标定时单击桌面


java.util.Timer.Timer 概述

1、java.util.Timer 是一个工具类计时器,线程用其安排以后在后台线程中执行的任务,可安排任务执行一次,或者定期重复执行。 

2、与每个 Timer 对象相对应的是单个后台线程,用于顺序地执行所有计时器任务。

3、Timer 计时器任务应该迅速完成,如果完成某个计时器任务的时间太长,那么它会“独占”计时器的任务执行线程。因此,这就可能延迟后续任务的执行,而这些任务就可能“堆在一起”,并且在上述不友好的任务最终完成时才能够被快速连续地执行。 

4、对 Timer 对象最后的引用完成后,并且所有未处理的任务都已执行完成后,计时器的任务执行线程会正常终止(并且成为垃圾回收的对象)。但是这可能要很长时间后才发生。

5、默认情况下,任务执行线程并不作为守护线程来运行,所以它能够阻止应用程序终止。如果调用者想要快速终止计时器的任务执行线程,那么调用者应该调用计时器的 cancel 方法。 

6、此类是线程安全的:多个线程可以共享单个 Timer 对象而无需进行外部同步,方法内部使用了 synchronized 加了对象锁。

构造方法摘要
Timer()   创建一个新计时器。
Timer(boolean isDaemon)   创建一个新计时器,可以指定其相关的线程作为守护程序运行。
Timer(String name)   创建一个新计时器,其相关的线程具有指定的名称。
Timer(String name, boolean isDaemon)   创建一个新计时器,其相关的线程具有指定的名称,并且可以指定作为守护程序运行。
方法摘要  
cancel() 终止此计时器,丢弃所有当前已安排的任务。
purge()  从此计时器的任务队列中移除所有已取消的任务。
schedule(TimerTask task, Date time)   安排在指定的时间执行指定的任务。
schedule(TimerTask task, Date firstTime, long period)   安排指定的任务在指定的时间开始进行重复的固定延迟执行
schedule(TimerTask task, long delay)   安排在指定延迟后执行指定的任务。
schedule(TimerTask task, long delay, long period)     安排指定的任务从指定的延迟后开始进行重复的固定延迟执行
scheduleAtFixedRate(TimerTask task, Date firstTime, long period)    安排指定的任务在指定的时间开始进行重复的固定速率执行
scheduleAtFixedRate(TimerTask task, long delay, long period) 安排指定的任务在指定的延迟后开始进行重复的固定速率执行

java.util.Timer.TimerTask 概述

public abstract class TimerTask implements Runnable {

1、由 Timer 安排为一次执行或重复执行的任务,它是抽象类,自己必须继承它然后重写 run 方法。

方法摘要
boolean cancel() 取消此计时器任务。
abstract  void run() 此计时器任务要执行的操作。
long scheduledExecutionTime() 返回此任务最近实际 执行的已安排 执行时间。

2、方法内部使用 synchronized(lock) 加了对象锁。

鼠标定时单击桌面

1、Java 中提供了很多用于自动化测试包,可以用来模拟用户进行如移动鼠标、单击鼠标、滚动鼠标滚轮、右击、按下一个或多个键盘按键等

2、下面的代码就是模拟用户自动单击桌面指定区域,每间隔1分钟,鼠标自动点击一次,测试一个晚上,时间误差完全可以忽略,非常稳定

代码实现

import java.awt.*;
import java.awt.event.InputEvent;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * Created by Administrator on 2018/6/23 0023.
 * 创建模拟用户单击的定时器任务
 * 可以创建一次执行或重复执行的任务
 * TimeTask 类似 Thread 类
 */
public class ClickTask extends TimerTask {
    //用户单击计数
    private AtomicInteger atomicInteger = new AtomicInteger(0);
    //同样实现run方法
    @Override
    public void run() {
        //单数次与偶数次分别单击桌面两个不同的位置
        if (atomicInteger.addAndGet(1) % 2 == 0) {
            clickScreenByXY(100, 300);
        } else {
            clickScreenByXY(1200, 300);
        }
        System.out.println(new Date() + " click " + atomicInteger.get() + " time ,Thread name is :" + Thread.currentThread().getName());
    }
    /**
     * 模拟用户单击屏幕指定区域,默认单击屏幕最中央
     * @param x:x坐标
     * @param y:y坐标
     */
    public static final void clickScreenByXY(Integer x, Integer y) {
        try {
            /**创建工具包对象*/
            Toolkit toolkit = Toolkit.getDefaultToolkit();
            /**创建自动化对象*/
            Robot robot = new Robot();
            /**利用工具包对象获取屏幕分辨率*/
            if (x == null) {
                x = toolkit.getScreenSize().width / 2;
            }
            if (y == null) {
                y = toolkit.getScreenSize().height / 2;
            }
            /**
             * 移动鼠标到指定位置
             * 然后按下鼠标左键,再松开,模拟单击操作
             */
            robot.mouseMove(x, y);
            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
            robot.delay(100);
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        // 创建定时任务
        TimerTask timerTask = new ClickTask();
        //创建定时器对象
        Timer timer = new Timer();
        /**相当于新开一个线程去执行定时器任务
         * 定时器执行定时器任务,3 秒后开始执行任务
         * 任务执行完成后,间隔 5 秒再次执行,循环往复
         */
        timer.schedule(timerTask, 3000, 5000);
    }
}

运行结果

Mon Mar 11 17:44:17 CST 2019 click 1 time ,Thread name is :Timer-0
Mon Mar 11 17:44:22 CST 2019 click 2 time ,Thread name is :Timer-0
Mon Mar 11 17:44:27 CST 2019 click 3 time ,Thread name is :Timer-0
Mon Mar 11 17:44:32 CST 2019 click 4 time ,Thread name is :Timer-0
Mon Mar 11 17:44:37 CST 2019 click 5 time ,Thread name is :Timer-0
Mon Mar 11 17:44:42 CST 2019 click 6 time ,Thread name is :Timer-0
Mon Mar 11 17:44:47 CST 2019 click 7 time ,Thread name is :Timer-0
....

注意事项

1、Runnable 的run() 或者 Callable的call() 方法执行完成时,线程就会自动结束

2、run 方法中发生了异常而没有被捕获处理时,那么此线程就会提前结束

3、所以定时器异常必须 try-catch 处理,可以参考《ScheduledExecutorService 详解1》

你可能感兴趣的:(Java_SE,线程_X)