I want o make threads execute at specific exact times (for example at: 2012-07-11 13:12:24 and 2012-07-11 15:23:45)
I checked ScheduledExecutorService, but it only supports executing after specific period from the first run and I don't have any fixed periods, instead I have times from database to execute tasks on.
In a previous question for a different problem here, TimerTask was the solution, but obviuosly I can't make thread a TimerTask as Runnable and TimerTask both have the method run which needs to be implemented. The question here if I make the thread extends TimerTask and have one implementation of run(), would that work?
If not, then how it's possible to do what I'm trying to do?
Use TimerTask .
Create a TimerTask object with a field variable as your thread.
Call the Thread start from the Timer task Run method.
public class SampleTask extends TimerTask {
Thread myThreadObj;
SampleTask (Thread t){
this.myThreadObj=t;
}
public void run() {
myThreadObj.start();
}
}
Configure it like this.
Timer timer new Timer();
Thread myThread= // Your thread
Calendar date = Calendar.getInstance();
date.set(
Calendar.DAY_OF_WEEK,
Calendar.SUNDAY
);
date.set(Calendar.HOUR, 0);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);
// Schedule to run every Sunday in midnight
timer.schedule(
new SampleTask (myThread),
date.getTime(),
1000 * 60 * 60 * 24 * 7
);
I think you should better use some library like the Quartz Scheduler. This is basically an implementation of cron for Java.
Have you looked at CountDownLatch from the java.util.concurrent package? It provides a count down then triggers the thread(s) to run. I never needed to use it myself, but have seen it in use a couple times.
Related
I'm trying to run a method once a week. For example, every Monday 8pm. I use this code:
Timer timer = new Timer();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
calendar.set(Calendar.HOUR_OF_DAY, 20);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
Date time = calendar.getTime();
timer.schedule(new PrintTask(),
time);
// other code where variable gets increased
public class PrintTask extends TimerTask {
public void run() {
variable = 0;
}
}
However, if I am right, the dosomething code is run continuously - as long as the calendar time has already passed. For example, now it has already been Monday, so the dosomething code is run all the time. A variabele gets increased, but it must be reset to 0 on Monday. The variable is now constantly 0, because it is reset again and again. If I use calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);, the variable is not reset, because it has not been Sunday yet. But as soon as it is Sunday 8pm, he will probably continue to reset the rest of that day.
I want the dosomething code to be executed only once at the one time specified. Can someone tell me how to adjust the code to achieve this?
Sorry for my English
Please look at this question here(How i can run my TimerTask everyday 2 PM). It almost deals with same kind of problem.
Cancel the timer using the cancel api of Timer class, and reschedule the timer inside the run() method; this should prevent from updating the variable everytime.
The Timer class can be used to schedule things to run once, or multiple times. The way you are scheduling it at this moment will only make it once at the given time.
https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html#schedule(java.util.TimerTask,%20java.util.Date)
There are better options if you want to schedule tasks, for example the ScheduledExecutorService:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
According to Java Concurrency in Practice:
Timer can be sensitive to changes in the system clock, ScheduledThreadPoolExecutor isn't.
Timer has only one execution thread, so long-running task can delay other tasks. ScheduledThreadPoolExecutor can be configured with
any number of threads. Furthermore, you have full control over created
threads, if you want (by providing ThreadFactory).
Runtime exceptions thrown in TimerTask kill that one thread, thus making Timer dead :-( ... i.e. scheduled tasks will not run anymore.
ScheduledThreadExecutor not only catches runtime exceptions, but it
lets you handle them if you want (by overriding afterExecute method
from ThreadPoolExecutor). Task which threw exception will be canceled,
but other tasks will continue to run.
http://jcip.net/
I am testing a few things with TimerTask and Timers and android , and i noticed that if i put Looper inside the run () method, the TimerTask runs just once, even though i defined it to be repetitive.Any ideas why is that ?
here is the MainActivity part
Timer timi=new Timer();
timi.scheduleAtFixedRate(new locac(nok,this),10, 1000);
and here is the worker timerTask class
public void run ()
{
Looper.prepare();
int loto=23;
int lato=23;
long time=1220227200;
String test=String.valueOf(lato);
String test3=String.valueOf(loto);
String test1=String.valueOf(time);
dbadapter mkola=new dbadapter(Ctx);
mkola.openToWrite();
mkola.insert(test,test1,test3);
Looper.loop();
}
as soon as i remove the Looper , it works nice.
i need the Looper because at a point i want to invoke some methods inside which initiate a Handler
thanks in advance
It is because your TimrTask never returns (because of the call to Looper.loop() )
Form The Timertask documentation, emphasis mine (Oracle Documentation, Android's is not that clear) http://docs.oracle.com/javase/7/docs/api/java/util/Timer.html
:
Corresponding to each Timer object is a single background thread that
is used to execute all of the timer's tasks, sequentially. Timer tasks
should complete quickly. If a timer task takes excessive time to
complete, it "hogs" the timer's task execution thread. This can, in
turn, delay the execution of subsequent tasks, which may "bunch up"
and execute in rapid succession when (and if) the offending task
finally completes.
So what happens is that your TimerTask is run in the single thread of your Timer and as it's run method never returns it bloks the thread, which cannot run the new scheduled itereation of your TimerTask anymore.
I am reading about timers in Java SDK 1.3
It is mentioned as follows in POSA volume 2 in active object pattern
JDK 1.3 introduced a mechansim for executing timer-based tasks
concurrently in the classes java.util.Timer and java.util.TimerTask.
When ever the scheduled execution time of a task occurs it is
executed. The scheduling calls are executed in the clinets thread,
while the tasks themselves are executed in a thread owned by Timer
object. A timer internal task queue is protected by locks because the
two threads outlined above operate on it concurrently.
The task queue is implemented as a priority queue so that the next
TimerTask to expire can be identified efficiently. The timer thread
simply waits until this expiration.
public class Reminder {
Timer timer;
public Reminder(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
System.out.format("Time's up!%n");
timer.cancel(); //Terminate the timer thread
}
}
public static void main(String args[]) {
new Reminder(5);
System.out.format("Task scheduled.%n");
}
}
My question is
Can we have multiple schedule functions with single timer? Request to give an example here and how it works. For example if we have two scheduled one task for every 5 seconds as shown above and another for every 12 seconds but I want to use same Reminder object instead of using another (i.e., creating) Reminder object. I want to know how internally it works like how timer stated like 5,5,2, 3, and so on . (as I have same kind of requirement in my project which I have to do in C++ with out using boost. I am planning to use single timer rather than multiple timers.
What is delay argument here and how it is used.
schedule(TimerTask task, long delay, long period)
Thanks for your time and help.
If you don't have to use SDK 1.3, you can use Java 5.0 which introduced the ScheduledExecutorService which makes Timers redundant IMHO.
The ScheduledExecutorService has been around more than 9 years, perhaps it is time to upgrade.
BTW 1.3 was end of lifed, before Sun officially had End of Life dates. It is ancient and unless you like history lessons, I suggest you live in the present. ;)
BTW Java 5.0 and Java 6 are both end of life and Java 7 will have its end of life date announced next year.
So I would look at Java 7 or 8 if I were you, and ignore anything which is more than a few years old because there are many practices which are either bad, or out dated on the Internet and they don't get updated.
If you like learning about bad or out of date practices, the rose india web site is the finest collection I have found. ;)
How do you activate or run a loop every tenth of a second? I want to run some script after an amount of time has passed.
Run a script every second or something like that. (notice the bolded font on every)
You can use a TimerTask. e.g.
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
You simply need to define a Runnable. You don't have to worry about defining/scheduling threads etc. See the Timer Javadoc for more info/options (and Quartz if you want much more complexity and flexibility)
Since Java 1.5:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new RepeatedTask(), 0, 100, TimeUnit.MILLISECONDS);
and
private class RepeatedTask implements Runnable {
#Override
public void run() {
// do something here
}
}
(remember to shotdown() your executor when finished)
You sleep.
Check out Thread.sleep() but be warned that you probably really don't want your whole program to sleep, so you might wish to create a thread to explicitly contain the loop and it's sleeping behavior.
Note that sleep only delays for a number of milliseconds; and, that number is not a perfect guarantee. If you need better time resolution you will have to use System.currentTimeMillis() and do the "time math" yourself. The most typical scenario is when you run something and you want it to run ever minute. The time the script runs must be captured by grabbing System.currentTimeMillis() before and after the script, and then you would need to sleep the remaining 1000 - scriptRunTime milliseconds.
I am using Timertask in my web application to launch a background thread once every 24 hrs every day at midnight. So I have a ServletContextListener and in contextInitialized, I create a Timertask object timertask(say) and a Timer object say t.
I call
t.schedule(timertask, firstTime.getTime(), rescheduleMiliSec);
where firstTime.getTime() = midnight and rescheduleMiliSec = 24 hr.
The thread launches fine and does what it is supposed to do in DIT.Every 24 hrs it launches the background task.
When it moves to PROD, the thread runs only once when context is initialised but not after that.
Is there any specific setting that might be the cause for this?
Is it possible your TimerTask implementation is throwing a RuntimeException?
If not an exception, then some TimerTask being scheduled in that Timer is blocking indefinitely. Those are the only two conditions that I am aware of that could cause a Timer to fail.
BTW, you might want to look into a ScheduledExecutorService. That is the more modern way of scheduling tasks.
I think the reason is simple but it may evade the naked eye.
firstTime.getTime()
is in milliseconds and the following method take precedence:
schedule(TimerTask task, long delay, long period)
insead of the intended:
schedule(TimerTask task, Date firstTime, long period)
In the contextInitialized method after scheduling a task using TimerTask , is there any code below that , may be that is causing an exception.