Create a task to run in an Interval
Bài đăng này đã không được cập nhật trong 7 năm
Khi chúng ta phát triển ứng dụng với java thỉnh thoảng chúng ta sẽ gặp những bài toán tạo một xử lý chạy trên background trong một khoảng thời gian.
Ví dụ: gửi dữ liệu lên server hay clean application...
Trong bài viết này mình xin giới thiệu với các bạn 3 cách để có thể giải quyết bài toán này trên java:
- Sử dụng
Thread
- Sử dụng
TimerTask
- Sử dụng
ScheduledExecutorService
Sử dụng Thread
Đây được xem là cách đơn giản và khá quen thuộc đối với nhiều lập trình viên. Chúng ta chỉ cần tạo một Thread
và cho nó chạy mãi mãi bằng việc dùng một vòng lặp vô hạn và sử dụng Thread.sleep(timeInterval)
để delay task
public class Task {
public static void main(String[] args) {
// run in a second
final long timeInterval = 1000;
Runnable runnable = new Runnable() {
public void run() {
while (true) {
// ------- code for task to run
System.out.println("Hello !!");
// ------- ends here
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
Việc bắt và xử lý ngoại lệ InterruptedException
là cần thiết vì nếu có ngoại lệ xảy ra thì task sẽ bị dừng lại ngay lập tức .
Sử dụng TimerTask
Sử dụng Thread
là một cách nhanh và cài đặt khá dễ dàng, tuy nhiên nó lại có một số hạn chế như:
- Không kiểm soát được lúc công việc bắt đầu hoặc bị hủy
- Không hỗ trợ time delay cho lần thực hiện đầu tiên
Khi sử dụng TimerTask, nó có thể giúp chúng ta giải quyết được những vấn đề trên.
Để cài đặt chúng ta sẽ sử dụng 2 đối tượng là
Timer
để lập lịch vàTimerTask
được dùng để thực hiện công việc trong hàmrun()
public class Task {
public static void main(String[] args) {
TimerTask task = new TimerTask() {
@Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
}
};
Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1 * 1000;
// schedules the task to be run in an interval
timer.scheduleAtFixedRate(task, delay,
intevalPeriod);
} // end of main
}
Sử dụng ScheduledExecutorService
Được giới thiệu trong gói java.util.concurrent
từ java 5. ScheduledExecutorService
là một cách được ưa thích để giải quyết bài toán của chúng ta
Việc sử dụng ScheduledExecutorService
sẽ mang lại cho chúng ta một số lợi ích như:
- Dễ dàng cho việc delay lần thực hiện đầu tiên
- Cung cấp những quy định cho việc cung cấp thời gian lặp lại task
ScheduledExecutorService có 3 method chính đó là:schedule()
, scheduleWithFixedDelay()
, scheduleAtFixedRate()
.
Thường chúng ta sẽ sử dụng 2 phuơng thức đó là: scheduleWithFixedDelay(
) và scheduleAtFixedRate()
.
Nói qua về sự khách nhau giữa 2 method này thì scheduleAtFixedRate()
và scheduleWithFixedDelay()
đều nhận vào những tham số giống nhau đó là một Runnable để thực thi task, thời gian delay trong lần thực thi đầu tiên, thời gian nghỉ và tham số cuối cùng là đơn vị thời gian. Tuy nhiên chúng lại có những điểm khác nhau về cách thực thi, scheduleWithFixedDelay()
sẽ đợi cho task thực thi xong và tiếp tục chờ hết thời gian nghỉ sau đó mới thực thi lại task đó, còn scheduleAtFixedRate()
sẽ thực thi task sau mỗi một khoảng thời gian nghỉ.
public static void main(String[] args) {
Runnable runnable = new Runnable() {
public void run() {
// task to run goes here
System.out.println("Hello !!");
}
};
ScheduledExecutorService service = Executors
.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.SECONDS);
}
Lưu ý:
Khi sử dụng ScheduledExecutorService
và TimerTask
chúng ta sẽ tránh được InterruptedException
tuy nhiên nếu trong hàm run() có xảy ra ngoại lệ thì task cũng sẽ bị dừng lại vì vậy chúng ta cần xem xét đến các trường hợp gây ra ngoại lệ và sử lý bắt ngoại lệ tại đây.
Hy vọng những cách trên có thể hữu ích với các bạn!!!
Tham khảo:
https://developer.android.com/reference/java/util/concurrent/ScheduledThreadPoolExecutor.html
All rights reserved