Java java.util.Timer là một lớp tiện ích có thể được sử dụng để lên lịch thực thi một luồng vào một thời điểm xác định trong tương lai. Lớp Java Timer có thể được dùng để lên lịch cho một tác vụ chạy một lần hoặc lặp lại theo chu kỳ đều đặn.

Java TimerTask
java.util.TimerTask là một lớp trừu tượng triển khai giao diện Runnable. Để tạo một tác vụ riêng có thể được lập lịch bằng lớp Java Timer, chúng ta cần mở rộng lớp TimerTask này.
Ví dụ về Java Timer
Lớp Java Timer là thread-safe, nghĩa là nhiều luồng có thể chia sẻ cùng một đối tượng Timer mà không cần đến cơ chế đồng bộ hóa (synchronization)bên ngoài. Lớp này sử dụng java.util.TaskQueue để thêm các task theo khoảng thời gian định sẵn. Ty nhiên, tại bất kỳ thời điểm nào, chỉ có một luồng thực thi TimerTask.
Ví dụ, nếu bạn tạo một Timer để chạy mỗi 10 giây, nhưng một lần thực thi lại mất 20 giây, thì đối tượng Timer vẫn sẽ tiếp tục thêm các task vào queue Ngay khi một luồng kết thúc việc xử lý, nó sẽ thông báo cho hàng đợi, và một luồng khác sẽ bắt đầu thực thi tiếp.
Lớp Timer trong Java sử dụng các phương thức wait và notify của đối tượng để lập lịch thực thi các task.
Dưới đây là một ví dụ đơn giản về cách sử dụng Java Timer và TimerTask.
package com.journaldev.threads;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class MyTimerTask extends TimerTask {
@Override
public void run() {
System.out.println("Timer task started at:"+new Date());
completeTask();
System.out.println("Timer task finished at:"+new Date());
}
private void completeTask() {
try {
//assuming it takes 20 secs to complete the task
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String args[]){
TimerTask timerTask = new MyTimerTask();
//running timer task as daemon thread
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(timerTask, 0, 10*1000);
System.out.println("TimerTask started");
//cancel after sometime
try {
Thread.sleep(120000);
} catch (InterruptedException e) {
e.printStackTrace();
}
timer.cancel();
System.out.println("TimerTask cancelled");
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Lưu ý: rằng mỗi lần một luồng thực thi sẽ mất 20 giây, trong khi đối tượng Java Timer được lập lịch để chạy task sau mỗi 10 giây.
Dưới đây là kết quả đầu ra của chương trình:
TimerTask started
Timer task started at:Wed Dec 26 19:16:39 PST 2012
Timer task finished at:Wed Dec 26 19:16:59 PST 2012
Timer task started at:Wed Dec 26 19:16:59 PST 2012
Timer task finished at:Wed Dec 26 19:17:19 PST 2012
Timer task started at:Wed Dec 26 19:17:19 PST 2012
Timer task finished at:Wed Dec 26 19:17:39 PST 2012
Timer task started at:Wed Dec 26 19:17:39 PST 2012
Timer task finished at:Wed Dec 26 19:17:59 PST 2012
Timer task started at:Wed Dec 26 19:17:59 PST 2012
Timer task finished at:Wed Dec 26 19:18:19 PST 2012
Timer task started at:Wed Dec 26 19:18:19 PST 2012
TimerTask cancelled
Timer task finished at:Wed Dec 26 19:18:39 PST 2012
Kết quả đầu ra xác nhận rằng nếu một task đang được thực thi, thì Timer sẽ chờ task đó hoàn tất rồi mới bắt đầu thực thi task tiếp theo từ hàng đợi.
Đối tượng Java Timer có thể được tạo để chạy các tác vụ liên kết dưới dạng daemon thread. Phương thức cancel() của Timer được dùng để hủy Timer và loại bỏ tất cả các task đã được lên lịch, tuy nhiên nó không can thiệp vào task đang chạy và vẫn cho phép task đó hoàn tất.
Nếu Timer được chạy như một daemon thread, thì dù bạn có gọi cancel() hay không, nó vẫn sẽ tự động kết thúc khi tất cả các luồng người dùng đã hoàn tất thực thi.
Lớp Timer cung cấp nhiều phương thức schedule() để lập lịch cho một task chạy một lần duy nhất vào một thời điểm cụ thể hoặc sau một khoảng trễ. Ngoài ra còn có các phương thức scheduleAtFixedRate() để thực hiện một task định kỳ theo một khoảng thời gian cố định.
Khi sử dụng Timer để lập lịch cho các task, bạn cần đảm bảo rằng khoảng thời gian giữa các lần chạy phải lớn hơn thời gian thực thi trung bình của task. Nếu không, hàng đợi các task sẽ ngày càng lớn, dẫn đến việc các tác vụ bị dồn và có thể sẽ luôn trong trạng thái thực thi liên tục.
Trên đây là phần tổng kết nhanh về Java Timer và Java TimerTask.