【问题标题】:Timer not able to execute task定时器无法执行任务
【发布时间】:2017-12-29 23:41:28
【问题描述】:

我正在尝试定期执行任务。例如:

class MyTimerTask implements TimerTask 
{
   public void run() {
     // Some actions to perform
   }
   Timer cleaner = new Timer(true);
   cleaner.scheduleAtFixedRate(new MyTimerTask(), 0, PURGE_INTERVAL);
}

但是,run 方法只执行一次。但是如果我把第一次延迟设置为 10 秒,那么run 方法甚至不会执行一次。

例子:

cleaner.scheduleAtFixedRate(new MyTimerTask(), 10, PURGE_INTERVAL);

【问题讨论】:

    标签: java timer scheduled-tasks timertask periodic-task


    【解决方案1】:

    我很难弄清楚你的问题到底是什么,所以这可能不是你所要求的,但这个解决方案可能适合你:

    public class MyTimerTask implements Runnable {
        private static final TimeUnit timeUnit = TimeUnit.SECONDS;
        private final ScheduledExecutorService scheduler;
        private final int period = 10;
        public static void main(String[] args) {
            new MyTimerTask();
        }
        public MyTimerTask() {
            scheduler = Executors.newScheduledThreadPool(1);
            scheduler.scheduleAtFixedRate(this, period, period, timeUnit);
        }
        @Override
        public void run() {
            // This will run every 10 seconds
            System.out.println("Ran...");
        }
    }
    

    【讨论】:

    • 所以缺少@Override?​​span>
    • 好吧,你能不能举一个“工作”的例子,因为你提供的代码不能运行,你在类声明中有声明等等。我不认为这就是为什么,因为它只是一个注解让编译器给你更好的帮助。
    【解决方案2】:

    对我来说,这听起来像是时间单位的问题。确保您正确转换为毫秒。

    最简单的方法是使用 Java 的 TimeUnit

    Timer cleaner = new Timer(true);
    cleaner.scheduleAtFixedRate(new MyTimerTask(),
        TimeUnit.SECONDS.toMillis(10),
        TimeUnit.SECONDS.toMillis(30));
    

    这也可能是由于Timer 以守护程序模式启动所致。如果您的 main 方法所做的只是设置计时器然后返回计时器将永远不会执行,因为它是最后一个剩余线程并且因为它是一个守护线程,JVM 将退出。

    要解决这个问题,要么让计时器线程不是守护进程(即在构造函数中传递false),要么让主线程在退出之前等待用户输入。

    以下是使用上述两种方法的示例:

    public class TimerDemo extends TimerTask {
    
        public void run() {
            System.out.printf("Time is now %s%n", LocalTime.now());
        }
    
        public static void main(String[] args) throws IOException {
            Timer timer = new Timer(true);
            timer.scheduleAtFixedRate(new TimerDemo(),
                    TimeUnit.SECONDS.toMillis(5),
                    TimeUnit.SECONDS.toMillis(10));
            System.out.printf("Program started at %s%n", LocalTime.now());
            System.out.println("Press enter to exit");
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
                // Wait for user to press enter
                reader.readLine();
            }
            System.out.println("Bye!");
        }
    }
    

    以及运行它的输出:

    Program started at 14:49:42.207
    Press enter to exit
    Time is now 14:49:46.800
    Time is now 14:49:56.799
    Time is now 14:50:06.799
    Time is now 14:50:16.799
    Time is now 14:50:26.799
    [I pressed 'enter']
    Bye!
    
    Process finished with exit code 0
    

    【讨论】:

    • 是的,你是对的 Raniz。问题是从 main 方法退出后 run 方法不执行。所以,我必须把 sleep 放在主线程中。
    • 如果它为您解决了问题,请随时接受我的回答。它通过在搜索结果中将此问题标记为已解决来帮助其他人。
    猜你喜欢
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 2012-11-21
    • 2011-03-31
    • 2012-11-11
    • 1970-01-01
    相关资源
    最近更新 更多