如何使用定时器重新安排任务?

7
这是我的问题,我正在使用JMS将一些消息发送到队列中。程序已经编写成这样:从前一个消息发送的时间开始,30秒内将会有一条消息发送到队列中。如果在30秒内没有发送任何消息,则该消息为最后一条消息,我应该开始从队列中消费消息。
我的初步想法是创建一个带有任务的定时器(在此处为从队列接收消息),当创建新消息时,调用该方法并等待30秒钟。如果再次调用该方法,那么就意味着另一条消息已经到来,因此必须重新安排任务。
这是我编写的代码:
public void startTimer() {
    Timer t = new Timer();
    try {
        t.schedule(task, timeDelay);
    } catch (Exception e) {
        t.cancel();
        t = new Timer();
        t.schedule(task, timeDelay);
    }
}

我正在尝试安排一个计时器,如果已有任务计划到该计时器上,则我将取消该计时器,创建一个新的计时器并安排一个新的任务。

我收到错误消息:任务已经被计划或取消

请问你有什么建议、改进或解决方案吗?欢迎提出。

3个回答

10

您不能在一个或多个计时器中使用相同的TimerTask

需要创建一个新的TimerTask实例才能执行:

t.cancel();
t = new Timer();
TimerTask newTask = new MyTimerTask();  // new instance
t.schedule(newTask, timeDelay);

可以选择使用 ScheduledExecutorService 并结合 Executors 进行实例化。 - Yaneeve

2

你确定计时器是正确的方法吗?听起来你应该使用最长等待时间来监听消息。类似这样的伪代码:

boolean timeout = false;
while (!timeout) {
  // Read a message within 30 seconds
  try {
    Message msg = consumer.receive( 30000 );
  } catch (JMSException jmse) {
    timeout=true;
  }

  // Process the message here
  process(msg);
}

// Timed-out while waiting for a message, so process messages in the queue
processQueue();

把这段代码放到一个函数中并重复调用。如果需要多线程功能,请将其包装在Thread或Runnable中。

1
重新使用你的定时器,并在取消后重新创建你的定时任务。存储任务以便稍后可以取消它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接