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

Java定时单次执行特定时长线程异常问题咨询

Alright, let's tackle this problem step by step. Your goal is to create a Java thread that starts after a specified delay, runs for a fixed duration (only once until called again), but right now it's stopping after one "Hi" print—unless you remove the stop flag, then it runs forever. Let's break down why this is happening and fix it.

Why Your Current Code Isn't Working

The most likely issue is that your thread's run() method only executes the print statement once, then immediately checks your stop flag and exits. Without a loop that keeps the thread active for your desired duration, it'll terminate right after the first iteration. If you remove the stop flag, there's no termination condition, so the thread runs infinitely.

Java's java.util.concurrent.ScheduledExecutorService is built exactly for these kinds of time-bound, scheduled tasks. It’s more reliable than manually managing threads and delays. Here’s a complete implementation that meets all your requirements:

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

public class TimedOneShotTask {
    // Single-threaded scheduler to handle our tasks safely
    private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    /**
     * Triggers a one-time task that starts after the specified delay, runs for the given duration, then stops.
     * Call this method again to run the task another time.
     * @param delay Time to wait before starting the task
     * @param duration How long the task should run
     * @param timeUnit Unit of time for delay and duration
     */
    public void startTask(long delay, long duration, TimeUnit timeUnit) {
        // Schedule the task to start after the specified delay
        scheduler.schedule(() -> {
            long endTime = System.currentTimeMillis() + timeUnit.toMillis(duration);
            
            // Loop until we hit the end time or the thread is interrupted
            while (System.currentTimeMillis() < endTime && !Thread.currentThread().isInterrupted()) {
                System.out.println("Hi");
                
                // Optional: Add a small sleep to avoid spamming the console (adjust as needed)
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    // Restore interrupted status so the loop exits cleanly
                    Thread.currentThread().interrupt();
                }
            }
        }, delay, timeUnit);
    }

    /**
     * Call this when you're done to shut down the scheduler cleanly
     */
    public void shutdown() {
        scheduler.shutdown();
    }

    // Example usage
    public static void main(String[] args) throws InterruptedException {
        TimedOneShotTask task = new TimedOneShotTask();
        
        // Start task after 2 seconds, run for 5 seconds
        task.startTask(2, 5, TimeUnit.SECONDS);
        
        // Wait for the task to finish, then shut down
        TimeUnit.SECONDS.sleep(8);
        task.shutdown();
    }
}

Key Details of This Implementation:

  • Delayed Start: The schedule() method handles waiting for your specified delay before launching the task.
  • Duration Control: We calculate an endTime based on the current time plus your desired duration. The loop runs until this time is reached.
  • Clean Interruption Handling: Properly handles thread interrupts so the task can exit gracefully if needed.
  • Single Execution: Each call to startTask() schedules a new one-time task—just call it again to run the task another time.

Alternative: Raw Thread Implementation (For Reference)

If you prefer to use a raw Thread instead of the executor service (not recommended for production code), here’s how to adjust your logic:

public class ManualTimedThread {
    public void startTask(long delayMillis, long durationMillis) {
        new Thread(() -> {
            // Wait for the specified delay before starting
            try {
                Thread.sleep(delayMillis);
            } catch (InterruptedException e) {
                return; // Exit early if interrupted during delay
            }
            
            long endTime = System.currentTimeMillis() + durationMillis;
            
            // Run until duration is up or interrupted
            while (System.currentTimeMillis() < endTime && !Thread.currentThread().isInterrupted()) {
                System.out.println("Hi");
                
                try {
                    Thread.sleep(500); // Avoid spamming the console
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }).start();
    }

    // Example usage
    public static void main(String[] args) throws InterruptedException {
        ManualTimedThread thread = new ManualTimedThread();
        thread.startTask(2000, 5000); // Start after 2s, run for 5s
    }
}

The core fix here is adding a loop that continues running until the specified duration has elapsed—something your original code was missing.

内容的提问来源于stack exchange,提问作者Mike S.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:59:53