I'm using Timer and TimerTask to long poll for new messages for a chat application. I would like to examine two "slightly" different possibilities:
1 : Timer declared as local variable
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
}
}
}
*Problem: Every time i call the method, i can see that a new thread is created, [Timer-1], [Timer-2], etc.. And in Eclipse Debug window they all seem to be running even after the getLastMessages(..) finishes running and returns a value to the client. This may cause a huge problem if the timers are actually using threads, and after few transactions the server will eventually consume all the machine resources.
2 : Timer declared as local field
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
}
}
}
*Problem: every time i call the method, the same thread is used [Thread-1], but i'm not sure if i make two consecutive calls, the latter will cancel/override the former (the class is @Autowired by spring) ?
Any suggestions ? Thank you.
There it states: "Corresponding to each Timer object is a single backgroundthread that is used to execute all of the timer's tasks, sequentially." - so yes, each Timer has its own thread but if you schedule 2 tasks on the same timer they will be executed sequentially.
Timer provides method to schedule Task where the task is an instance of TimerTask class, which implements the Runnable interface and overrides run() method to define task which is called on scheduled time.
Use timer. scheduleAtFixedRate() to schedule it to recur every two seconds: Schedules the specified task for repeated fixed-rate execution, beginning at the specified time. Subsequent executions take place at approximately regular intervals, separated by the specified period.
Here is the source code of the schedule
method:
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 }
and the sched
method:
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 }
From here you can clearly see that a queue is being used to store tasks internally, meaning that later tasks will not overwrite the earlier ones. If you also check the mainLoop
method in the file, you can see that it takes tasks from the queue one-by-one ordered by their schedule time and executes them.
So it should not be a problem to schedule multiple tasks on the same Timer
object.
As a side-note, consider replacing Timer
with ScheduledThreadPoolExecutor
available since Java 1.5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With