Java 执行 scheduled task
Java Timer
Timer 用于执行一个 scheduled task,它提供了如下 schedule 方法:
public void schedule(TimerTask task, long delay);
public void schedule(TimerTask task, Date time);
public void schedule(TimerTask task, long delay, long period);
public void schedule(TimerTask task, Date firstTime, long period);
public void scheduleAtFixedRate(TimerTask task, long delay, long period);
public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period);
如上方法中:
- TimerTask 实现 Runnable 接口可被 schedule 执行一次或多次
- delay 定义 task 被 schedule 到执行所延迟的时间,time 定义 task 执行的时间
- period 指周期行执行 task 的时间间隔
使用示例
TimerTask 的实现如下,它的任务是输出当前时间戳:
public class TestTimerTask extends TimerTask {
public void run() {
System.out.println(System.currentTimeMillis());
}
}
如下代码演示周期性的运行 TimerTask:
Timer timer = new Timer("Test Timer", true);
TimerTask task = new TestTimerTask();
timer.schedule(task, 5000, 2000);
Thread.currentThread().sleep(Long.MAX_VALUE);
Timer 将会在 5000 毫秒后运行 TimerTask,且循环的运行 TimerTask,两次运行的时间间隔为 2000 毫秒。TimerTask 在没有执行的时候处于 wait 状态,它的线程 dump 如下:
"Test Timer" #9 daemon prio=5 os_prio=0 tid=0x00007f7da80db800 nid=0x19e4 in Object.wait() [0x00007f7d8befd000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d7f7c0a8> (a java.util.TaskQueue)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000000d7f7c0a8> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
Locked ownable synchronizers:
- None
Java ScheduledExecutorService
ScheduledExecutorService 实现 ExecutorService 接口,它提供了如下 schedule 方法:
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
如上方法中:
- command 是一个 Runnable Task,可以被执行一次或多次
- delay 定义 task 被 schedule 到执行所延迟的时间
- period 定义多次执行 task 的时间间隔
使用示例
如下代码演示使用 ScheduledExecutorService 周期性的执行 4 个 Runnable Task,每个 Task 的任务是输出 线程的名称和当前系统时间戳:
final ThreadGroup threadGroup = new ThreadGroup("TestService ThreadGroup");
final String namePattern = "TestService Thread Pool -- %t";
final ThreadFactory threadFactory = new JBossThreadFactory(threadGroup, Boolean.FALSE, null, namePattern, null, null, doPrivileged(GetAccessControlContextAction.getInstance()));
ScheduledThreadPoolExecutor scheduledExecutorService = new ScheduledThreadPoolExecutor(4 , threadFactory);
scheduledExecutorService.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
for(int i = 0 ; i < 4 ; i ++) {
scheduledExecutorService.scheduleAtFixedRate(new Runnable(){
public void run() {
System.out.println(Thread.currentThread().getName() + ": " + System.currentTimeMillis());
}}, 5, 2, TimeUnit.SECONDS);
}
ScheduledExecutorService 将会在 5 秒钟之后周期性的执行 4 个 Runnable Task,且每两个 Task 之间的时间间隔为 2 秒钟,Runnable Task 没有被执行时状态如下:
"TestService Thread Pool -- 1" #10 prio=5 os_prio=0 tid=0x00007f1cc030a000 nid=0x1faf waiting on condition [0x00007f1c8955c000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000d8232688> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Locked ownable synchronizers:
- None