目录
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);
}
}
在线演示源码:https://gitee.com/wangmx1993/java-se/blob/master/src/test/java/org/example/se/ClickTask.java
运行结果
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》