Làm cách nào để lên lịch một tác vụ định kỳ trong Java?


183

Tôi cần lên lịch cho một nhiệm vụ để chạy trong khoảng thời gian cố định. Làm thế nào tôi có thể làm điều này với sự hỗ trợ của các khoảng thời gian dài (ví dụ trên mỗi 8 giờ)?

Tôi hiện đang sử dụng java.util.Timer.scheduleAtFixedRate. Có java.util.Timer.scheduleAtFixedRatehỗ trợ khoảng thời gian dài?

Câu trả lời:


260

Sử dụng một dịch vụ theo lịch trình :

 private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
 scheduler.scheduleAtFixedRate(yourRunnable, 8, 8, TimeUnit.HOURS);

1
Nếu bạn muốn điều này chạy mỗi ngày vào một thời điểm cụ thể thì không phải là một cách tuyệt vời để làm điều đó, bởi vì TimeUnitáp dụng cho cả initialDelayperiod. Chạy mỗi 24 giờ sẽ kết thúc được ném ra khi đá DST, nhưng một TimeUnitsố DAYSkhông cho phép bạn chỉ định một hạt mịn initialDelay. (Tôi nghĩ rằng việc triển khai Nội bộ theo Lịch trình ExecutorService chuyển đổi DAYSthành nano giây dù thế nào đi nữa).
Sam Barnum

46

Bạn nên xem Quartz đó là một khung công tác java hoạt động với các phiên bản EE và SE và cho phép xác định các công việc để thực hiện một thời gian cụ thể


23

Hãy thử theo cách này ->

Trước tiên, tạo một TimeTask lớp chạy nhiệm vụ của bạn, nó trông giống như:

public class CustomTask extends TimerTask  {

   public CustomTask(){

     //Constructor

   }

   public void run() {
       try {

         // Your task process

       } catch (Exception ex) {
           System.out.println("error running thread " + ex.getMessage());
       }
    }
}

sau đó trong lớp chính, bạn khởi tạo tác vụ và chạy nó định kỳ bắt đầu trước một ngày được chỉ định:

 public void runTask() {

        Calendar calendar = Calendar.getInstance();
        calendar.set(
           Calendar.DAY_OF_WEEK,
           Calendar.MONDAY
        );
        calendar.set(Calendar.HOUR_OF_DAY, 15);
        calendar.set(Calendar.MINUTE, 40);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);



        Timer time = new Timer(); // Instantiate Timer Object

        // Start running the task on Monday at 15:40:00, period is set to 8 hours
        // if you want to run the task immediately, set the 2nd parameter to 0
        time.schedule(new CustomTask(), calendar.getTime(), TimeUnit.HOURS.toMillis(8));
}

6
Để làm cho mã dễ đọc hơn, bạn có thể thay đổi đối số cuối cùng trong lịch trình cuộc gọi đến TimeUnit.HOURS.toMillis (8)
darrenmc

Thay vào đó, tài liệu dành cho Timer khuyên bạn nên sử dụng khung Executor.
Karan Khanna

14

Sử dụng Google Guava AbstractScheduledServicenhư được đưa ra dưới đây:

public class ScheduledExecutor extends AbstractScheduledService
{
   @Override
   protected void runOneIteration() throws Exception
   {
      System.out.println("Executing....");
   }

   @Override
   protected Scheduler scheduler()
   {
        return Scheduler.newFixedRateSchedule(0, 3, TimeUnit.SECONDS);
   }

   @Override
   protected void startUp()
   {
       System.out.println("StartUp Activity....");
   }


   @Override
   protected void shutDown()
   {
       System.out.println("Shutdown Activity...");
   }

   public static void main(String[] args) throws InterruptedException
   {
       ScheduledExecutor se = new ScheduledExecutor();
       se.startAsync();
       Thread.sleep(15000);
       se.stopAsync();
   }

}

Nếu bạn có nhiều dịch vụ như thế này, thì việc đăng ký tất cả các dịch vụ trong ServiceManager sẽ tốt vì tất cả các dịch vụ có thể được bắt đầu và dừng lại cùng nhau. Đọc ở đây để biết thêm về ServiceManager.


9

Nếu bạn muốn gắn bó java.util.Timer, bạn có thể sử dụng nó để lên lịch trong khoảng thời gian lớn. Bạn chỉ cần vượt qua trong khoảng thời gian bạn đang chụp. Kiểm tra tài liệu ở đây .


5

Hai lớp này có thể làm việc cùng nhau để sắp xếp một nhiệm vụ định kỳ:

Nhiệm vụ theo lịch trình

import java.util.TimerTask;
import java.util.Date;

// Create a class extending TimerTask
public class ScheduledTask extends TimerTask {
    Date now; 
    public void run() {
        // Write code here that you want to execute periodically.
        now = new Date();                      // initialize date
        System.out.println("Time is :" + now); // Display current time
    }
}

Chạy tác vụ theo lịch trình

import java.util.Timer;

public class SchedulerMain {
    public static void main(String args[]) throws InterruptedException {
        Timer time = new Timer();               // Instantiate Timer Object
        ScheduledTask st = new ScheduledTask(); // Instantiate SheduledTask class
        time.schedule(st, 0, 1000);             // Create task repeating every 1 sec
        //for demo only.
        for (int i = 0; i <= 5; i++) {
            System.out.println("Execution in Main Thread...." + i);
            Thread.sleep(2000);
            if (i == 5) {
                System.out.println("Application Terminates");
                System.exit(0);
            }
        }
    }
}

Tham khảo https://www.mkyong.com/java/how-to-run-a-task- định kỳ-in-java /


Giải pháp tốt nhất cho đến bây giờ, sạch sẽ và dễ thực hiện hơn
Salvador Vigo


4

Làm gì đó cứ sau một giây

Timer timer = new Timer();
timer.schedule(new TimerTask() {
    @Override
    public void run() {
        //code
    }
}, 0, 1000);

1
Thay vào đó, tài liệu dành cho Timer khuyên bạn nên sử dụng khung Executor
Karan Khanna

3

Tôi sử dụng tính năng của Spring Framework. ( jar bối cảnh mùa xuân hoặc phụ thuộc maven).

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


@Component
public class ScheduledTaskRunner {

    @Autowired
    @Qualifier("TempFilesCleanerExecution")
    private ScheduledTask tempDataCleanerExecution;

    @Scheduled(fixedDelay = TempFilesCleanerExecution.INTERVAL_TO_RUN_TMP_CLEAN_MS /* 1000 */)
    public void performCleanTempData() {
        tempDataCleanerExecution.execute();
    }

}

Lịch trình là giao diện của riêng tôi với thực thi phương thức tùy chỉnh của tôi, mà tôi gọi là nhiệm vụ theo lịch trình của mình.


2

Bạn đã thử Spring Lập lịch bằng cách sử dụng các chú thích?

@Scheduled(cron = "0 0 0/8 ? * * *")
public void scheduledMethodNoReturnValue(){
    //body can be another method call which returns some value.
}

bạn có thể làm điều này với xml là tốt.

 <task:scheduled-tasks>
   <task:scheduled ref = "reference" method = "methodName" cron = "<cron expression here> -or- ${<cron expression from property files>}"
 <task:scheduled-tasks>

0

Servlet của tôi chứa mã này dưới dạng mã làm thế nào để giữ điều này trong lịch trình nếu người dùng nhấn chấp nhận

if(bt.equals("accept")) {
    ScheduledExecutorService scheduler=Executors.newScheduledThreadPool(1);
    String lat=request.getParameter("latlocation");
    String lng=request.getParameter("lnglocation");
    requestingclass.updatelocation(lat,lng);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.