Sử dụng Cron4J trong việc lập lịch chạy các nghiệp vụ trên Java

From CodeForLife
Jump to: navigation, search

Cron4j là thư viện java nhỏ, nhẹ, đơn giản, dễ sử dụng trong việc lập lịch chạy các nghiệp vụ trên Java. Với thư viện này, bạn có thể thực hiện một công việc bất kỳ vào đúng thời điểm bạn cần theo một số quy tắc đơn giản. Theo tôi Cron4J có một số điểm mạnh:

  • Thư viện nhẹ, nhỏ gọn, và miễn phí.
  • Lập trình rất dễ vì bạn chỉ cần nhớ vài phương thức.
  • Chạy trên mọi phiên bản Java.
  • Cú pháp cấu hình lập lịch đơn giản nhưng rất linh hoạt

Bạn có thể vào trực tiếp trang của dự án [1] để tải về hoặc lấy trực tiếp từ địa chỉ: File:Cron4j-2.2.5.zip

Lập trình với thư viện Cron4J

Việc lập trình sử dụng Cron4J rất đơn giản theo 04 bước như sau:

  • B1: Tạo một đối tượng là thể hiện lớp Scheduler (it.sauronsoftware.cron4j.Scheduler
  • B2: Lập lịch để thực hiện tác vụ của bạn tại thời điểm bạn muốn. Lịch được lập bằng một xâu theo định dạng SchedulingPattern (it.sauronsoftware.cron4j.SchedulingPattern). Còn để thực hiện tác vụ bạn có thế sử dụng đối tượng Runnable (java.lang.Runnable) hoặc Task (it.sauronsoftware.cron4j.Task). 
  • B3: Khởi chạy đối tượng Scheduler 
  • B4: Dừng chạy đối tượng Scheduler nếu bạn không muốn làm gì thêm.

Dưới dây là đoạn mã ví dụ, xâu "* * * * *" xác định tác vụ được thực hiện hàng phút:

import it.sauronsoftware.cron4j.Scheduler;

public class Quickstart {
	public static void main(String[] args) {
		// Tạo một đối tượng Scheduler
		Scheduler s = new Scheduler();

		// Lập lịch và xác định tác vụ cần thực hiện
		s.schedule("* * * * *", new Runnable() {
			public void run() {
				System.out.println("Another minute ticked away...");
			}
		});

		// Khởi chạy đối tượng
		s.start();

		// Chờ 10 phút
		try {
			Thread.sleep(1000L * 60L * 10L);
		} catch (InterruptedException e) {
			;
		}

		// Dừng tác vụ
		s.stop();
	}
}

Ví dụ trên chạy trong 10 phút. Mỗi phút sẽ in ra màn hình câu thông báo "Another minute ticked away...".

Cấu hình đặt lịch (Scheduling pattern)

Cron4J sử dụng Scheduling Pattern để cấu hình đặt lịch thực hiện, cấu hình tương tự như crontab trên UNIX. Đơn vị thời gian nhỏ nhất cho phép là phút.
Xâu cấu hình này được chia thành 05 phần như sau:

  • Minutes sub-pattern: Xác định phút nào tác vụ được chạy. Nhận giá trị từ 0 đến 59.
  • Hours sub-pattern: Xác định giờ nào tác vụ được chạy. Nhận giá trị từ 0 đến 23.
  • Days of month sub-pattern: Xác định ngày nào trong tháng tác vụ được chạy. Nhận giá trị từ 1 đến 31, và giá trị đặc biệt "L" để xác định ngày cuối tháng.
  • Months sub-pattern: Xác định tháng nào trong năm tác vụ được chạy. Nhận giá trị từ 1 (January) đến 12 (December), và giá trị alias tháng: "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov" và "dec".
  • Days of week sub-pattern: Xác định thứ mấy trong tuần tác vụ được chạy. Nhận giá trị từ 0 (Sunday) đến 6 (Saturday), và giá trị aliass như: "sun", "mon", "tue", "wed", "thu", "fri" và "sat".

Mỗi phần này theo chuẩn sau:

  • Kí tự * xác định mọi giá trị.
  • Kí tự , (phẩy) được sử dụng nếu có nhiều giá trị.
  • Kí tự - xác định dải giá trị. Ví dụ a-b tức là từ a đến b.
  • Kí tự / (slash) xác định bước nhảy thời gian.
  • Kí tự | nếu bạn muốn sử dụng kết hợp nhiều xâu pattern.

Bạn có thể kết hợp lại để tạo được xâu pattern mà bạn muốn. Dưới đây là một số ví dụ:

  • 5 * * * *
    Mẫu này xác định tác vụ sẽ được chạy vào phút thứ 5 hàng giờ. Ví dụ: 00:05, 01:05, 02:05...
  • * * * * *
    Mẫu này xác định mỗi phút tác vụ sẽ được thực hiện 1 lần.
  • * 12 * * Mon
    Mẫu này xác định tác vụ sẽ được thực hiện từng phút trong khoảng thời gian 12h của ngày thứ 2.
  • * 12 16 * Mon
    Mẫu này xác đinh tác vụ sẽ được thực hiện từng phút trong khoảng 12h thứ 2 ngày 16. Nếu vào ngày 16 mà không phải là thứ 2 thì tác vụ cũng sẽ không được thực hiện.
  • 59 11 * * 1,2,3,4,5
    Tác vụ này sẽ được thực hiện vào lúc 11:59AM vào các ngày Thứ Hai, Thứ Ba, Thứ tư, Thứ 5 và Thứ 6.
  • 59 11 * * 1-5
    Mẫu này tương đương với mẫu 59 11 * * 1,2,3,4,5 ở trên.
  • */5 * * * *
    Mẫu này xác định cứ 5 phút tác vụ sẽ được thực hiện một lần. Ví dụ: 0:00, 0:05, 0:10; 0:15,...
  • 3-18/5 * * * *
    Mẫu này xác định tác vụ sẽ được thực hiện 5 phút 1 lần trong khoảng thời gian từ phút thứ 3 đến phút thứ 18. Ví dụ: 0:03, 0:08, 0:13, 0:18, 1:03, 1:08,...
    • /15 9-17 * * *
      Mẫu này xác định tác vụ được thự hiện 15 phút 1 lần trong khoảng thời gian từ 9h đến 17h. Ví dụ: 9:00, 9:15, 9:30, 9:45,..., 17:45.
    • 12 10-16/2 * *
      Mẫu này xác định tác vụ được thực hiện từng phút vào lúc 12h trong các ngày mùng 10, 12, 14, 16 của tháng.
    • 12 1-15,17,20-25 * *
      Mẫu này xác định tác vụ sẽ được thực hiện từng phút vào lúc 12h trong các ngày từ mùng 1 đến 15, ngày 17 và từ ngày 20 đến ngày 25.
  • 0 5 * * *|8 10 * * *|22 17 * * *
    Mẫu này xác định tác vụ được thực hiện hàng ngày vào lúc 05:00, 10:08 và 17:22.

Ví dụ demo

Phần này sẽ làm ví dụ demo, lớp chính là ScheduleDemo có hàm main sử dụng đối tượng it.sauronsoftware.cron4j.Scheduler để đặt lịch chạy hai nghiệp vụ:

  • DemoBusiness01: Lớp này implement từ lớp java.lang.Runnable, được đặt lịch chạy từng phút. Cứ mỗi 01 phút hàm run sẽ được gọi, tại đây các bạn có thể cài đặt nghiệp vụ xử lý.
  • DemoBusiness02: Lớp này thực hiện theo cách khác, kế thừa từ lớp it.sauronsoftware.cron4j.Task, được đặt lịch chạy 5 phút một lần. Cứ mỗi 05 phút hàm execute sẽ được gọi, tại đây các bạn có thể cài đặt nghiệp vụ xử lý.

Cấu trúc của project như sau (Sử dụng IDE là Netbeans):

RTENOTITLE

Chi tiết source code như sau:

Tệp ScheduleDemo.java:

package com.mobilesoftvn.examples;

import com.mobilesoftvn.examples.business.DemoBusiness01;
import com.mobilesoftvn.examples.business.DemoBusiness02;
import it.sauronsoftware.cron4j.Scheduler;

/**
 * @author DaoThang
 */
public class ScheduleDemo {

    public static void main(String[] args) {
        // Tạo một đối tượng Scheduler
        // Lập lịch để từng phút thực hiện nghiệp vụ DemoProcess01
        Scheduler s1 = new Scheduler();
        s1.schedule("* * * * *", new DemoBusiness01());
        s1.start();

        // Tạo một đối tượng Scheduler
        // Lập lịch để cứ 5 phút thực hiện nghiệp vụ DemoProcess02
        Scheduler s2 = new Scheduler();
        s2.schedule("*/5 * * * *", new DemoBusiness02());
        s2.start();

        // Chờ 20 phút để xem kết quả
        try {
            Thread.sleep(1000L * 60L * 10L);
        } catch (InterruptedException e) {
        }

        // Dừng tác vụ
        s1.stop();
        s2.stop();
    }
}

Tệp DemoBusiness01.java:

package com.mobilesoftvn.examples.business;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author DaoThang
 */
public class DemoBusiness01 implements Runnable {

    @Override
    public void run() {
        System.out.println("DemoProcess01: Process at " + getCurrentTimeStamp());
    }

    private String getCurrentTimeStamp() {
        SimpleDateFormat sdfDate = new SimpleDateFormat("HH:mm:ss dd-MM-yyyy");
        Date now = new Date();
        String strDate = sdfDate.format(now);
        return strDate;
    }
}

Tệp DemoBusiness02.java:

package com.mobilesoftvn.examples.business;

import it.sauronsoftware.cron4j.Task;
import it.sauronsoftware.cron4j.TaskExecutionContext;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author DaoThang
 */
public class DemoBusiness02 extends Task{
    @Override
    public void execute(TaskExecutionContext tec) {
        System.out.println("DemoProcess02: Process at " + getCurrentTimeStamp());
    }
    
    private String getCurrentTimeStamp() {
        SimpleDateFormat sdfDate = new SimpleDateFormat("HH:mm:ss dd-MM-yyyy");
        Date now = new Date();
        String strDate = sdfDate.format(now);
        return strDate;
    }
}

Và đây là output khi chay (Bạn chú ý thời gian):

RTENOTITLE

Bạn có thể download source code demo tại: File:ScheduleDemo.zip