....
public class mainClass {
public mainClass(){
Timer time = new Timer();
mainClass.calculate calculate = new mainClass.calculate();
time.schedule(calculate, 1 * 1000);
}
public static void main(String[] args){
new mainClass();
}
class calculate extends TimerTask{
#Override
public void run() {
System.out.println("working..");
}
}
}
I saw only one times "working.." message in the console.I want to saw every second "working.." whats the problem on code? and my another problem i want to running every second my own method but how?
Sory for my bad english..
Timer.schedule(TimerTask task, long delay) only runs the TimerTask once, after the number of milliseconds in the second argument.
To repeatedly run the TimerTask, you need to use one of the other schedule() overloads such as Timer.schedule(TimerTask task, long delay, long period), for example:
time.schedule(calculate, 1000, 1000);
which schedules the task to be executed 1000 milliseconds from now, and to repeat every 1000 milliseconds.
It is supposed to be one time according to the documentation:
public void schedule(TimerTask task,
long delay) Schedules the specified task for execution after the specified delay. Parameters: task - task to be
scheduled. delay - delay in milliseconds before task is to be
executed. Throws: IllegalArgumentException - if delay is negative, or
delay + System.currentTimeMillis() is negative. IllegalStateException
- if task was already scheduled or cancelled, or timer was cancelled.
you probably want to call
public void schedule(TimerTask task,
long delay,
long period)
You need to use:
zaman.schedule(calculate, 0, 1000);
to schedule the timer to run more than once.
You need to wait in your main thread for the timer to be fired. The JVM will exit when all the non daemon threads are completed. The thread that runs your main method is actually the only non damon thread so you should make it wait until your work is complete.
Change your main method like this:
public static void main(String[] args){
new mainClass();
Thread.sleep(2 * 1000); // wait longer than what the timer
// should wait so you can see it firing.
}
The version of Timer.schedule() which you are using only executes the task once after a delay. You need to use `Timer.schedule(TimerTask, long, long) to cause the task to repeat.
Related
I have an agent-based model that I need to update every t milliseconds. In each update step, all the agent objects need to be notified and execute some code. I want every step to last t or until the last step has finished, whatever is longer.
How can I do this? I'm trying to use Timer.schedule, but it doesn't seem to be waiting because I'm getting a ConcurrentModificationException.
public void startClock(long delay) {
Timer timer = new Timer("clock", true);
TimerTask clockTask = new TimerTask() {
#Override
public void run() {
World.INSTANCE.update(); //this updates all agents
step++;
for (Timed task : listeners) {
task.run();
}
}
};
timer.schedule(clockTask, delay, interval); //miliseconds
}
public void startClock() {
startClock(interval);
}
Take a look at ScheduledExecutorService#scheduleAtFixedRate(). It will execute your task either every t milliseconds or immediately after the last execution if it took longer than t.
You can also evaluate Akka Scheduler. It ensures that there will be no overlap of executions of the runnable. Here's the snippet from their documentation-
If the execution of the runnable takes longer than the interval, the subsequent execution will start immediately after the prior one completes (there will be no overlap of executions of the runnable). In such cases, the actual execution interval will differ from the interval passed.
I have a requirement that, with in a time duration (suppose it is 50 sec, the time might be dynamic) i have to fetch some data from a server.
At the same time every 10sec (in between this 30 sec), I have to send some keys to server.
for that iam using below code....but it is not working
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long duration = (50 * 1000);
do {
// RESEt request call code goes here..
/////
//////
System.out.println("Rest request");
java.util.Timer t = new java.util.Timer();
java.util.TimerTask task = new java.util.TimerTask() {
#Override
public void run() {
//Sending key every 10 sec
RemoteKey.send(PageUp);
}
};
t.schedule(task, 0, (10 * 1000));
// This do while loop will execute 50 sec
} while ((System.currentTimeMillis() - startTime) < duration);
}
Why not schedule once, and cancel itself?
long duration=whatever;
java.util.Timer timer = new java.util.Timer();
java.util.TimerTask task = new java.util.TimerTask() {
long t0=System.currentTimeMilis(); // or set it upon scheduling;
#Override
public void run() {
//this will stop the task from executing in future.
if((System.currentTimeMillis() - t0) >= duration) { this.cancel(); return;}
// do actual work
RemoteKey.send(PageUp);
}
};
timer.scheduleAtFixedRate(task,initialDelay,delayBetweenActions);
More modern approach would be to use ScheduledExecutorService.
I think you should use RxJava and Job Scheduler to schedule the task at particular interval.
For example:
Observable.interval(50, TimeUnit.SECONDS)
.doOnNext(n -> performYourtask())
.subscribe();
This would be the optimal approach, using the modern ScheduledExecutor
As the timespan of, say 50 seconds, is ruled by the fetching operation, and that operation is synchronous, you'll just have to wait for it to end.
// Start the executor, scheduling your Runnable Task to run every 10 seconds
executorService.scheduleAtFixedRate(
() -> {
// Send your data
}, 0, 10, TimeUnit.SECONDS);
// Fetch data from your Server.
// That's a blocking operation, which, let's say will take 50 seconds
// Stop the Executor as the time is over
executorService.shutdown();
The Executor can be created via Factory method.
Executors.newScheduledThreadPool(5); // For multiple, concurrent threads
Executors.newSingleThreadScheduledExecutor(); // For a synchronous "queue"
I need to executable a Runnable implementation at intervals of time that can keep changing and is adjusted by another thread. Can I achieve this using SchedulerExecutorService and ScheduleWithFixedDelay ? Will doing this:
ThreadScheduler = backgroundExecutors.scheduleWithFixedDelay(refreshFunc, 5, refreshRate, TimeUnit.SECONDS);
check the value of the variable refreshRate and adapt accordingly ?
I do not want to put the thread on sleep via a variable like this :
Thread.sleep(variable);
I would be thankful to anyone who can provide some useful information here.
EDIT:
I will rephrase my question. If I have to change the time interval associated with scheduleWithFixedDelay, is it possible when the task execution is progress.
EDIT 2:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
ScheduledFuture scheduledFuture;
Runnable foo = new Runnable() {
public void run() {
doSomething();
}
}
while (true) {
scheduledFuture = scheduledExecutorService.schedule(foo, refreshRate, TimeUnit.SECONDS);
scheduleFuture.cancel();
}
Please note that refreshRate keeps changing. Will this work ?
EDIT 3:
ScheduledExecutorService scheduleExecutorService = Executors.newScheduledThreadPool(5);
ScheduleFuture scheduledFuture;
Runnable foo = new Runnable() {
public void run() {
doSomething();
}
scheduledFuture.cancel():
scheduleFuture = scheduledExecutorService.schedule(foo, refreshRate, TimeUnit.SECONDS);
}
scheduleFuture = scheduledExecutorService.schedule(foo, refreshRate, TimeUnit.SECONDS);
enter code here
So is this what you are suggesting ?
scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) gives you, as the name hints, a fixed delay between executions. The interval between executions is fixed by the parameter delay. Once scheduled, it's not possible to change the scheduling parameters. You would need to cancel the scheduledFuture and issue a new command.
If your scheduling time between runs is variable, an option will be to read the next execution time at the end of your job run and let it schedule a new execution using: schedule(Runnable command, long newDelay, TimeUnit unit)
I used Object.wait(timeout) in my android app service. But it does not count time spent in "deep sleep mode". I use AlarmManager to wakeup my app periodically, so waking from deep sleep is not the problem. The problem is that wait(60000) not terminates after 100 seconds of deep sleep.
As i read on SystemClock help page, object.wait uses uptimeMillis() method, which stops counting in deep sleep. For my needs it will be better to use elapsedRealtime().
How can i implement an analogue of Object.wait(timeout) but using elapsedRealtime method? Or what can i use instead?
One of the tasks i use this method for is to generate "ping" packet to send via network when no other packets are in queue for some amount of time.
Instead of using plain Object.wait() or Thread.sleep() I would suggest you to use any of the following:
Use a java.util.concurrent.newScheduledThreadPool which gives you ability to schedule a task with fixed interval or delay. Initializing the thread pool with threadCount = 1 gives you a single thread.
Use a java.util.Timer which allows you to schedule TimerTask.
I think 1. is a preferred method.
In case you have specific requirement that you want to plug in your timer object or use a specific or 3rd party timing provider, what you need to do is to write your own scheduler which wraps the ScheduledExecutorService, then convert the time using your own timer or get time from your own timer. Basically you launch a scheduled task on the wrapped service with your own time calculation.
I have a sample of such scheduler in my actor model as below. Take a look at the DefaultScheduler in this package. It might be a bit buggy (I haven't tested it fully yet) but it should give you a good idea.
http://sourceforge.net/p/jalgo/code-0/HEAD/tree/trunk/src/org/as/algo/threading/
You mentioned(at comments) interrupt() causes termination(kill) the thread, while this is completely wrong, it just throws an exception to the waiting/joining/sleeping thread.
public void Foo implements Runnable{
public void run(){
//do some work
try{Thread.sleep(10000);}catch(Exception ex){/*when thread got interrupted*/}
//do something else
}
}
the issue is here, because you put all the business inside a try block, so interrupting causes code jump into the catch block where there is no any business after this, so this is not a thread thing.
Not sure if it does exactly what you want but I wrote this to pause for a certain period of time but to let other threads wake me up prematurely.
It uses a BlockingQueue internally to do it's sleeping so it avoid using sleep and wait and all the grief that comes with them.
Not sure how it would act under Android, I don't work with it, but I suspect your existing AlarmManager work will adapt.
/**
* Use one of these to doze for a certain time.
*
* The dozing is fully interruptable.
*
* Another thread can stop the caller's doze with either a wakeup call or an abort call.
*
* These can be interpreted in any way you like but it is intended that a Wakeup is
* interpreted as a normal awakening and should probably be treated in exactly the
* same way as an Alarm. An Abort should probably be interpreted as a suggestion
* to abandon the process.
*/
public class Doze {
// Special alarm messages.
public enum Alarm {
// Standard timeout.
Alarm,
// Forced wake from your doze.
Wakeup,
// Abort the whole Doze process.
Abort;
}
// My queue to wait on.
private final BlockingQueue<Alarm> doze = new ArrayBlockingQueue<>(1);
// How long to wait by default.
private final long wait;
public Doze(long wait) {
this.wait = wait;
}
public Doze() {
this(0);
}
public Alarm doze() throws InterruptedException {
// Wait that long.
return doze(wait);
}
public Alarm doze(long wait) throws InterruptedException {
// Wait that long.
Alarm poll = doze.poll(wait, TimeUnit.MILLISECONDS);
// If we got nothing then it must be a normal wakeup.
return poll == null ? Alarm.Alarm : poll;
}
public void wakeup() {
// Just post a Wakeup.
doze.add(Alarm.Wakeup);
}
public void abort() {
// Signal the system to abort.
doze.add(Alarm.Abort);
}
private static long elapsed ( long start ) {
return System.currentTimeMillis() - start;
}
// Test code.
public static void main(String[] args) throws InterruptedException {
// Doze for 1 second at a time.
final Doze d = new Doze(1 * 1000);
final long start = System.currentTimeMillis();
// Start a dozing thread.
new Thread(new Runnable() {
#Override
public void run() {
try {
Alarm a = d.doze();
// Wait forever until we are aborted.
while (a != Alarm.Abort) {
System.out.println(elapsed(start) + ": Doze returned " + a);
a = d.doze();
}
System.out.println(elapsed(start) + ": Doze returned " + a);
} catch (InterruptedException ex) {
// Just exit on interrupt.
}
}
}).start();
// Wait for a few seconds.
Thread.sleep(3210);
// Wake it up.
d.wakeup();
// Wait for a few seconds.
Thread.sleep(4321);
// Abort it.
d.abort();
}
}
Here is the use case:
I am using Java (with Spring)
Once the user (through a web-app) confirms to the subscription, I want to send him an email exactly after 30 mins.
Now how to do this? Do I need a message broker? or something like ScheduledExecutorService?
Do I need some sort of queue?
Please advise.
Can look into quartz scheduler for this.
By the way a common strategy is to send a bulk of all pending mails in bulk in every 30 minutes or so. Quartz can help in do that as well.
You can use the Quartz Scheduler. Its fairly easy to use. You can schedule something every week or ever 30 minutes or whatever you want basically.
Create an object for Timer
private Timer myTimer;
in main method
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
//your method
}
}, 0, 200);
It is not that the thread will die after sending the mail. When you configure Quartz, a new thread will automatically be created and will execute the assigned task on specified interval. Or else you use Timer class also. It is very easy to use.
Timer timer = new Timer(); // Get timer
long delay = 30 * 60 * 1000; // 3o min delay
// Schedule the two timers to run with different delays.
timer.schedule(new MyTask(), 0, delay);
...................
class MyTask extends TimerTask {
public void run() {
// business logic
// send mail here
}
}