我使用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)?
有什么建议吗?非常感谢。
以下是调度方法的源代码:
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 多个线程