2010-03-29 38 views
6

Tôi có một ứng dụng cần thực hiện một số hành động mỗi ngày thay đổi nói vào lúc nửa đêm. Bất cứ khi nào ngày thay đổi, ứng dụng sẽ được cho là giống nhau. Bất kỳ trợ giúp nào về cách triển khai chức năng sẽ được đánh giá cao.Cách theo dõi ngày thay đổi trong Java

Trả lời

7

Điều bạn đang tìm kiếm là bộ lập lịch. Quartz có lẽ là bộ lập lịch phổ biến nhất được sử dụng trong thế giới Java, mặc dù Spring có một số tính năng lập lịch thú vị nếu bạn đã sử dụng khung công tác đó.

Bất kỳ trình lên lịch nào bạn chọn, bạn thường chỉ định một hành động xảy ra (đôi khi được gọi là "công việc") và một thời gian để xảy ra ("kích hoạt" trong thuật ngữ thạch anh). Trong trường hợp của bạn, bạn sẽ kích hoạt để chạy mỗi ngày vào lúc nửa đêm, và khi nó bắn nó sẽ làm bất cứ điều gì bạn cần làm, như được chỉ định bởi công việc của bạn.

1

Là thư viện, bạn có thể sử dụng Quartz và đặt trình kích hoạt để chạy vào nửa đêm mỗi đêm. Tôi nghĩ những người khởi xướng đơn giản nên thực hiện công việc.

Hoặc, bạn có thể thực hiện những gì Quartz tự làm, bằng cách sử dụng một sợi riêng biệt và ngủ cho đến nửa đêm tiếp theo.

-1

Nếu bạn không muốn Quartz hoặc bất kỳ khung nào khác như vậy, bạn có thể chỉ cần sử dụng phương pháp scheduleAtFixedRate của ScheduledExecutorService thay thế (có một ví dụ về cách khởi tạo một tại JavaDoc).

Điều duy nhất bạn phải suy nghĩ là cách tính điểm bắt đầu của ngày đầu tiên.

Sửa

Như Jarnbjo nêu: Điều này sẽ không tồn tại Daylight Saving Time tắc và nhảy-giây. Vì vậy, hãy nhận thức được điều này, khi sử dụng Executor.

+0

Điều đó sẽ không hiệu quả, vì nửa đêm không tái diễn ở mức cố định. – jarnbjo

+0

Chắc chắn, nhưng trong hầu hết các trường hợp, điều này không quan trọng chút nào. – Hardcoded

+0

Nếu bạn muốn một cái gì đó được thực hiện vào lúc nửa đêm, nó có thể _not_ ok nếu công việc được thực hiện 11PM hoặc 1AM. Trong đó "hầu hết các trường hợp" là hành vi được chấp nhận này? – jarnbjo

0

Câu trả lời cho câu hỏi này từng là Quartz. Đây là tiêu chuẩn defacto để lập kế hoạch trong Java. Nó là khá dễ sử dụng nhưng nó là một chút nặng. Nếu bạn không quan tâm đến việc lập kế hoạch nhóm hoặc lưu trữ JDBC các công việc, thạch anh có thể là quá mức cần thiết.

Rất may Spring 3.0 đi kèm với các tính năng lập lịch biểu mới. Điều này cho phép đơn giản 'làm điều này evey 30 giây' hoặc 'làm điều này hàng ngày vào lúc nửa đêm' các loại lịch trình mà không cần sử dụng thạch anh. Nếu bạn đã sử dụng mùa xuân thì nó khá dễ thiết lập.

Ví dụ:

<task:scheduler id="scheduler" pool-size="10"/> 

<task:scheduled-tasks scheduler="scheduler"> 
    <task:scheduled ref="anotherObject" method="anotherMethod" cron="* * 00 * * *"/> 
</task:scheduled-tasks> 

này sẽ gây ra những phương pháp 'anotherMethod' được kêu gọi bạn đậu có tên là 'anotherObject' lúc nửa đêm hàng ngày. Bạn có thể tìm thêm thông tin trên trang web của mùa xuân: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html

+1

Hmm, gọi thạch anh hạng nặng so với mùa xuân ... – laura

+0

@ laura Rất nhiều người đã có Spring làm phụ thuộc cho IoC. Tôi sẽ không đề nghị bao gồm mùa xuân chỉ cho tính năng này, nhưng nếu bạn đang sử dụng mùa xuân, đây là trọng lượng nhẹ hơn so với kéo trong tất cả các thạch anh. –

0

Bạn không cần một khung công tác bloaty lớn. Một cái gì đó như thế này sẽ làm việc.

import java.util.*; 
public class Midnight { 
    public static void main(String args[]) { 
     MidnightCowboy mc = new MidnightCowboy(); 
     mc.start(); 
     // on with you normal program flow (if any) here 
    } 
} 

class MidnightCowboy extends Thread { 
    static final boolean COWS_COME_HOME = false; 
    // Whatever data you need should go here 

    public void run() { 
     while (! COWS_COME_HOME) { 
      GregorianCalendar now = new GregorianCalendar(); 
      long nowMilli = now.getTimeInMillis(); 
      now.add(Calendar.DAY_OF_MONTH, 1);  // probably an easier way to set the time to the next midnight 
      now.set(Calendar.HOUR_OF_DAY, 0); 
      now.set(Calendar.MINUTE, 0); 
      now.set(Calendar.SECOND, 0); 
      now.set(Calendar.MILLISECOND, 0); 
      long midnightMilli = now.getTimeInMillis(); 
      long delta = midnightMilli - nowMilli; 
      System.out.println("Waiting " + delta + " milliseconds until midnight."); 
      // How many milliseconds until the next midnight? 
      try { 
       sleep(delta); 
       doSomething(); 
      } catch (InterruptedException e) { 
       System.err.println("I was rudely interrupted!"); 
      } 
     } 
    } 

    void doSomething() { 
     // whatever 
    } 
} 
0

Nếu bạn muốn có giải pháp gọn nhẹ hơn toàn bộ thư viện, tôi thấy việc triển khai khá đơn giản here. Về cơ bản nó là một lớp học Timer.

Khi lớp đầu tiên được thực hiện thông qua phương thức Start(), mã có được một datetime của thời điểm hiện tại, sau đó được một đối tượng datetime của nửa đêm và trừ đi 2 lần để cung cấp cho một thời gian cho đến khi nó là nửa đêm.

Với thời gian này, nó đặt khoảng thời gian hẹn giờ và bắt đầu hẹn giờ. Bây giờ khi đạt đến khoảng thời gian và bộ đếm thời gian kích hoạt sự kiện của nó, tôi đặt lại bộ hẹn giờ bằng cách sử dụng cùng một quy trình. Điều này sẽ làm cho khoảng thời gian cho 24. Khi bộ đếm thời gian này hết hạn, nó sau đó được thiết lập lại và lặp đi lặp lại vô thời hạn.

Các vấn đề liên quan