当前位置: 首页 > 知识库问答 >
问题:

java计时器任务多线程

顾曾笑
2023-03-14

我使用Timer和TimerTask为聊天应用程序长轮询新消息。我想研究两种“稍微”不同的可能性:

1:计时器声明为局部变量

public List<MessageBean> getLastMessages(...) {
    [...]
    Timer timer = new Timer(true); //**Timer declared as local variable**
    while (someCondiction) {
        MessagesTimerTask returnMessagesTask = new MessagesTimerTask([...]);
        timer.schedule(returnMessagesTask, 6000);
        synchronized (listMessageBean) {
            listMessageBean.wait();
            //notify is called in the MessagesTimerTask which extends TimerTask
        }
    }
}

*问题:每次调用该方法时,我都会看到创建了一个新线程,[Timer-1]、[Timer-2]等等。。在Eclipse调试窗口中,即使在getLastMessages(..)之后,它们似乎都在运行完成运行并向客户端返回值。如果计时器实际使用线程,并且在几次事务之后,服务器最终将消耗所有机器资源,那么这可能会导致一个巨大的问题。

2:计时器声明为本地字段

private final Timer timer = new Timer(true); //**Timer declared as local field**

public List<MessageBean> getLastMessages(...) {
    [...]
    while (someCondiction) {
        MessagesTimerTask returnMessagesTask = new MessagesTimerTask([...]);
        timer.schedule(returnMessagesTask, 6000);
        synchronized (listMessageBean) {
            listMessageBean.wait();
            //notify is called in the MessagesTimerTask which extends TimerTask
        }
    }
}

*问题:每次调用方法时,都使用相同的线程[Thread-1],但我不确定如果我连续调用两次,后者会取消/覆盖前者(该类在Spring之前是@Autowire)?

有什么建议吗?非常感谢。

共有1个答案

祁坚壁
2023-03-14

以下是调度方法的源代码:

190       public void schedule(TimerTask task, long delay) {
191           if (delay < 0)
192               throw new IllegalArgumentException("Negative delay.");
193           sched(task, System.currentTimeMillis()+delay, 0);
194       }

和sched方法:

386       private void sched(TimerTask task, long time, long period) {
387           if (time < 0)
388               throw new IllegalArgumentException("Illegal execution time.");
389   
390           // Constrain value of period sufficiently to prevent numeric
391           // overflow while still being effectively infinitely large.
392           if (Math.abs(period) > (Long.MAX_VALUE >> 1))
393               period >>= 1;
394   
395           synchronized(queue) {
396               if (!thread.newTasksMayBeScheduled)
397                   throw new IllegalStateException("Timer already cancelled.");
398   
399               synchronized(task.lock) {
400                   if (task.state != TimerTask.VIRGIN)
401                       throw new IllegalStateException(
402                           "Task already scheduled or cancelled");
403                   task.nextExecutionTime = time;
404                   task.period = period;
405                   task.state = TimerTask.SCHEDULED;
406               }
407   
408               queue.add(task);
409               if (queue.getMin() == task)
410                   queue.notify();
411           }
412       }

从这里你可以清楚地看到一个队列被用来在内部存储任务,这意味着以后的任务不会覆盖以前的任务。如果你也检查文件中的main Loop方法,你可以看到它从队列中逐个获取按计划时间排序的任务并执行它们。

因此,在同一个计时器上调度多个任务应该不是问题。

作为附带说明,考虑将Timer替换为Java1.5以来可用的schduledThreadPoolExector

 类似资料:
  • 本文向大家介绍java实现多线程之定时器任务,包括了java实现多线程之定时器任务的使用技巧和注意事项,需要的朋友参考一下 在Java中Timer是java.util包中的一个工具类,提供了定时器的功能。我们可以创建一个Timer对象,然后调用其schedule方法在某个特定的时间去执行一个特定的任务。并且你可以让其以特定频率一直执行某个任务,这个任务是用TimerTask来描述的,我们只需要将要

  • 但是我不能在一个计时器中处理不同的“计时器任务”。我试图将计时器任务对象添加到构造函数中,但是当我将新的计时器任务(RemindTask1)对象作为参数(内部类的实例)传递时,出现编译错误。 以下是它如何处理一项任务: 但是我完全被多个任务应该如何创建然后运行所困扰。 但是这不起作用,我不知道出了什么问题。当我将新的RemindTask2()作为参数传递时,我遇到了编译错误。

  • 我的计时器任务没有正常工作。我计划每3秒钟重复一次特定的任务,但这并没有发生。 根据Java文件: 计划(TimerTask任务、长延迟、长周期)。将指定的任务安排为重复的固定延迟执行,从指定的延迟后开始。随后的执行大约按规定的时间间隔定期进行。 但我只有一个“新任务!!!!”控制台打印 我是不是遗漏了什么? 谢谢 更新: 我将尝试在这里粘贴每一段相关的代码,从上到下执行。 开始:

  • 我有一个Java的计时器任务来生成每日报告。当我通过linux终端调用Java类(调度定时器任务),而不是在给定时间调度第一次运行时,它会在命令执行后立即运行。有人能建议为什么会这样吗... 我使用的计划它。 忘了补充一下,我使用的是java 1.5,这里是def方法 代码片段:

  • 基本上,我想做的是制作一个计时器,在x秒后运行一个特定的TimerTask,但是TimerTask可以重新安排计时器在y秒后执行任务。下面是一个示例,它在我试图在TimerTask run中调度此任务的行上给出了一个错误“线程中的异常”Timer-0“java.lang.IllegalStateException:任务已调度或已取消”。

  • 主要内容:1 如何使用多个线程执行一个任务,2 如何使用多个线程执行多个任务1 如何使用多个线程执行一个任务 如果需要由多个线程执行单个任务,则只有一个run()方法,例如: 1.1 多个线程执行一个任务示例1 输出结果为: 1.2 多个线程执行一个任务示例2 输出结果为: 注意:每个线程在单独的堆栈中运行。 2 如何使用多个线程执行多个任务 如果必须通过多个线程执行多个任务,请使用多个run() 方法: 2.1 多个线程执行多个任务示例1 输出结果为: 2.2 多个线程