You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中重复执行多个任务并在指定时间后停止?

Got it, let's build out a complete, robust solution for running multiple repeating tasks that automatically stop after a set amount of time. You’re already on the right track with ScheduledExecutorService—it’s way more reliable than managing raw Thread instances for scheduled work. Here’s a fully working implementation with explanations of key parts:

Complete Implementation for Multiple Repeating Tasks with Auto-Stop

Step 1: Full Working Code

import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledMultiTaskRunner {

    public static void main(String[] args) {
        // Configure how long to run all tasks before stopping (e.g., 15 seconds)
        final long RUN_DURATION_SECONDS = 15;

        // Create a scheduled thread pool with enough threads for parallel task execution
        // We have 2 tasks here, so a pool size of 2 ensures they run concurrently
        ScheduledExecutorService taskExecutor = Executors.newScheduledThreadPool(2);

        // --------------------------
        // Define your repeating tasks
        // --------------------------
        Runnable helloTask = () -> {
            try {
                System.out.println("Hello World! | Current time: " + LocalDateTime.now().toLocalTime());
            } catch (Exception e) {
                // Critical: Catch exceptions to prevent the task from being dropped by the executor
                System.err.println("Hello task failed: " + e.getMessage());
            }
        };

        Runnable statusCheckTask = () -> {
            try {
                System.out.println("Status Check: All tasks running | Time: " + LocalDateTime.now().toLocalTime());
            } catch (Exception e) {
                System.err.println("Status task failed: " + e.getMessage());
            }
        };

        // --------------------------
        // Schedule tasks to repeat
        // --------------------------
        // Task 1: Starts immediately, repeats every 2 seconds
        taskExecutor.scheduleAtFixedRate(helloTask, 0, 2, TimeUnit.SECONDS);

        // Task 2: Starts after a 1-second delay, repeats every 3 seconds
        taskExecutor.scheduleAtFixedRate(statusCheckTask, 1, 3, TimeUnit.SECONDS);

        // --------------------------
        // Schedule auto-stop after RUN_DURATION_SECONDS
        // --------------------------
        taskExecutor.schedule(() -> {
            System.out.println("\n--- Time's up! Stopping all tasks ---");

            // Graceful shutdown: Stop accepting new tasks, wait for running tasks to finish
            taskExecutor.shutdown();

            try {
                // Wait up to 5 seconds for tasks to complete gracefully
                if (!taskExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
                    // Force shutdown if tasks don't finish in time
                    System.out.println("Forcing shutdown of remaining tasks...");
                    taskExecutor.shutdownNow();
                }
            } catch (InterruptedException e) {
                // If we're interrupted while waiting, force shutdown immediately
                taskExecutor.shutdownNow();
                // Restore the interrupted status for the calling thread
                Thread.currentThread().interrupt();
            }

            System.out.println("All tasks have stopped successfully.");
        }, RUN_DURATION_SECONDS, TimeUnit.SECONDS);
    }
}

Key Components Explained

Let’s break down the important parts to make sure you understand how everything works:

  • Thread Pool Size: We use newScheduledThreadPool(2) because we have 2 tasks. Using a pool size matching your task count ensures tasks run in parallel without waiting for each other. If you have more tasks, adjust the number accordingly.
  • Exception Handling in Tasks: Each task includes a try-catch block. If a task throws an uncaught exception, ScheduledExecutorService will stop scheduling that task entirely—so catching exceptions ensures your task keeps running even if something goes wrong.
  • scheduleAtFixedRate vs scheduleWithFixedDelay:
    • We use scheduleAtFixedRate here, which schedules the next run based on the start time of the previous run (e.g., every 2 seconds, regardless of how long the task takes).
    • If you want the next run to start after the previous task finishes, use scheduleWithFixedDelay instead.
  • Graceful Shutdown:
    • shutdown() tells the executor to stop accepting new tasks and let existing ones finish.
    • awaitTermination() waits a set time for tasks to complete. If they don’t finish in time, shutdownNow() forces them to stop by interrupting running threads.
  • Auto-Stop Trigger: We use taskExecutor.schedule() to run the shutdown logic after our desired run duration. This avoids needing a separate monitoring thread.

Bonus: Cancel Individual Tasks

If you ever need to stop just one task instead of all of them, you can capture the ScheduledFuture returned by scheduleAtFixedRate and call cancel() on it:

// Capture the future when scheduling the task
ScheduledFuture<?> helloTaskFuture = taskExecutor.scheduleAtFixedRate(helloTask, 0, 2, TimeUnit.SECONDS);

// Later, cancel the task (false = don't interrupt if it's currently running)
helloTaskFuture.cancel(false);

内容的提问来源于stack exchange,提问作者user3718160

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:23:23