简体   繁体   English

带有线程的Java Timer

[英]Java Timer with thread

I develop a simple application and I use timer, but if I run the timer several times the timer drops this exception: Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Timer already cancelled. 我开发了一个简单的应用程序,并使用了计时器,但是如果我多次运行计时器,计时器将丢弃此异常:线程“ AWT-EventQueue-0”中的异常java.lang.IllegalStateException:计时器已取消。 Here is my code: 这是我的代码:

public class Main {

...
private static void createAndShowUI() {
    ...
    //a listener of a radio button
    ActionListener on_action = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Timer.timer.schedule(Timer.task,0,2000);   //I call the timer here 
        }
    };
    ...
}
public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
            createAndShowUI();
          }
        });
 }


}
//and the class of timer:
public class Timer {


public static java.util.Timer timer = new java.util.Timer();
public static java.util.TimerTask task = new java.util.TimerTask() {


    public void run() {
        //some tasks
    }
};
}

My question is that where I use the thread? 我的问题是,我在哪里使用线程? Thanks! 谢谢!

The problem is not using the Event-Queue thread, it is that you are re-using a cancelled Timer. 问题不在于使用事件队列线程,而是您正在重新使用已取消的计时器。

I'm guessing you are using the Timer to do some animation or something in response to a button push (as you schedule things at a fixed rate). 我猜想您正在使用计时器来做一些动画或响应按钮按下的操作(因为您以固定的速度安排事物)。 I'm guessing also that in code you don't show us, the timer gets cancelled by a separate event. 我也在猜测,在代码中您不向我们展示,计时器会被一个单独的事件取消。 If you ever call Timer.cancel() can you show us that code? 如果您曾经调用过Timer.cancel(),可以向我们展示该代码吗?

From the exception what is happening is that you are trying to use the same Timer that you have already cancelled. 从例外情况来看,您正在尝试使用已经取消的计时器。 Once a Timer has been cancelled, it can't be used again. 一旦取消计时器,将无法再次使用它。

Two suggestions - use a different Timer every time. 两个建议-每次使用不同的计时器。 Also, if you are doing things for UI purposes, you might want to consider using a Swing timer instead . 此外,如果您出于UI目的而做事,则可能要考虑使用Swing计时器

As far as the Thread goes, all GUI events happen on the AWT Thread, but I repeat, this is almost certainly not the problem. 就线程而言,所有GUI事件都在AWT线程上发生,但是我重复一遍,这几乎肯定不是问题。 Read this for more details. 阅读此以获得更多详细信息。

A timer goes into cancelled state if either the cancel() method has been invoked or the if the timer task has terminated unexpectedly: 如果已调用cancel()方法或计时器任务意外终止,则计时器将进入取消状态:

If the timer's task execution thread terminates unexpectedly, for example, because its stop method is invoked, any further attempt to schedule a task on the timer will result in an IllegalStateException, as if the timer's cancel method had been invoked. 如果计时器的任务执行线程意外终止,例如,由于调用了它的stop方法,则在计时器上计划任务的任何进一步尝试都将导致IllegalStateException,就好像计时器的cancel方法已被调用一样。

So in your case, it may not be a problem of where you put/call/use your time, but more a problem of what you're actually doing with your timer. 所以你的情况,它可能不是把/电话/使用时间的问题,但你实际上你的计时器做什么更多的问题。

Here you have your thread: 这是线程:

Corresponding to each Timer object is a single background thread that is used to execute all of the timer's tasks, sequentially 与每个Timer对象相对应的是一个后台线程,该线程用于依次执行所有Timer的任务

so if you try to access your GUI from the Timer task you should put it into the EventQueue thread. 因此,如果您尝试从Timer任务访问GUI,则应将其放入EventQueue线程中。

And look here 看看这里

If the timer's task execution thread terminates unexpectedly, for example, because its stop method is invoked, any further attempt to schedule a task on the timer will result in an IllegalStateException, as if the timer's cancel method had been invoked. 如果计时器的任务执行线程意外终止,例如,由于调用了它的stop方法,则在计时器上计划任务的任何进一步尝试都将导致IllegalStateException,就好像计时器的cancel方法已被调用一样。

Do you let the Timer schedule any more tasks after it has been cancelled? 取消计时器后,是否让计时器安排其他任务?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM