I am trying to simulate a live data stream, to test a program that is constantly filtering and computing data points. Mainly I need to make sure that it will meet timing.
Every 50 milliseconds there will be a new data point that will need to be computed on.
So I would like to create a java clock that is independent of what is currently running in the jvm or anything like that happening on the system.
So my question is two fold:
first of all, System.currentTimeMillis() will not be what I want here because it is based on when the jvm was opened, and it would happen when ever the system call gets executed.
second, how do i make a thread that will be constantly running and always trigger exactly on the 50ms mark?
There's pretty good, pre-defined mechanism (comparing to pure threading) of Timers and TimerTask:
import java.util.Timer;
import java.util.TimerTask;
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");
}
}
(took from: http://enos.itcollege.ee/~jpoial/docs/tutorial/essential/threads/timer.html)
This mechanism allows you to execute your code in RemindTask's run() method every 5 seconds (that value was specified in code)
Take a look at ScheduledExecutorService, more specifically the scheduleAtFixedRate() method.
It allows you to perform an operation at regular intervals.
Take a look at ScheduledExecutorService.
Here is an example:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
//New data point
}
}, 0, 50,TimeUnit.MILLISECONDS );
Related
How do I run a specific set of instructions inside the TimerTask continuously without delay for a set amount of time ? Below are the codes I am attempting to implement the above.
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
System.out.println("Test started at: " + new Date());
// Do something continuously without delay
System.out.println("Test finished at: " + new Date());
}
}, 0);
The second parameter to the schedule method is the time to begin the timer task (or delay relative to now), not the length of time that the timer will execute for.
It's not completely clear from your question but I'm assuming you want the task to start and stop at particular times (or delays relative to now) in the future. If so, the way I would approach this is to create a Thread that does the task you need. Since a TimerTask is a Runnable that is executed as a Thread once the Timer starts it, you can just use an instance of that TimerTask. Ensure that Runnable contains a settable field like running. In that Thread, run your task in a while loop like this:
public void run() {
while(running) { /* do my task */ }
}
Then, use one Timer to schedule the Runnable to start at the time you need. Use another Timer to set the running parameter of the same Thread to false at the time you want it to stop. The running parameter should be volatile to ensure that changes to it from the second timer Thread are seen by the first timer Thread immediately. So it would look something like this (not tested):
class StoppableTimerTask extends TimerTask {
private volatile boolean running = true;
public void stopRunning() { this.running = false; }
public void run() {
while(running) { /* do my task */ }
}
}
final StoppableTimerTask task = new StoppableTimerTask();
timer.schedule(task, startTime);
timer.schedule(new TimerTask() {
public void run() {
task.stopRunning();
}
}, stopTime);
Depending on what your "something" is, you may also want to look into Thread interrupts. For example, if it is doing blocking IO, your code won't loop and check the running value until the blocking IO completes. Interrupting the thread (may) cause that to happen. See http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#interrupt--. This may or may not work, and it can be tricky to get right, so if you need this Thread to exit as close to the desired time as possible, prefer running blocking I/O and similar operations with smaller timeouts so that the thread can check whether it should continue to run more often.
UPDATE: As per the comment indicating that the task should start right away, it becomes even simpler. The initial task doesn't even need to extend TimerTask -- it can just be a regular Thread that is started immediately. The timer is only needed to stop it at the specified future time.
I want to create a thread which never halts. Every second it will acquire the system time and display this on the console. This is what I have so far:
public class Test implements Runnable {
#Override
public void run() {
System.out.println(System.currentTimeMillis());
}
}
I'd like to avoid using a loop.
Using while(true) and TimeUnit.SECONDS.sleep is a possibility, but it is bad practice (as you can see from the sheer number of downvotes on this post). This SO answer gives some reasons as to why:
low level, subject to spurious wakeups
clock drift
control
intent of code
there are others.
The basic way to achieve this is to use a java.util.Timer, not to be confused with a javax.swing.Timer:
final Timer timer = new Timer("MyTimer");
timer.schedule(new TimerTask() {
#Override
public void run() {
System.out.println(System.currentTimeMillis());
}
}, 0, TimeUnit.SECONDS.toMillis(1));
You need to call timer.cancel() to stop the timer - as the timer is running a non-daemon thread your program will not exit until that is done.
A more advanced way, which allows multiple tasks to be scheduled to run at different intervals on a pool of the ScheduledExecutorService. This allows you to scheduleAtFixedRate which runs a task every second (regardless of how long it takes to run, i.e. the gap between start times is always the same) or scheduleWithFixedDelay which runs a task at one second intervals (i.e. the gap between the end of one run and the start of the next is always the same).
For example:
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
final ScheduledFuture<?> handle = executorService.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
System.out.println(System.currentTimeMillis());
}
}, 0, 1, TimeUnit.SECONDS);
To cancel the particular task you would call handle.cancel(false) (as interrupting has no effect) and to stop the executorService you would call executorService.shutdown() after which you might want to add a executorService.awaitTermination(1, TimeUnit.DAYS) to wait for all the tasks to finish.
EDIT
A comment This can be done more concisely in java 8 with lambda right? (not an expert at lambdas)
The first example, no. A Timer takes a TimerTask, this is an abstract class and not an #FunctionalInterface so a lambda is not possible. In the second case, sure:
final ScheduledFuture<?> handle = executorService.
scheduleAtFixedRate(() -> System.out.println(System.currentTimeMillis()), 0, 1, TimeUnit.SECONDS);
I'm trying to test the use of time in Java to manipulate code. So let's say I have a app with an egg. The egg won't hatch until 60 seconds have passed in the application, what method or class would I use to do this?
The Timer class should do what you are after:
A facility for threads to schedule tasks for future execution in a background thread. Tasks
may be scheduled for one-time execution, or for repeated execution at
regular intervals.
You can take a look at a simple example available here.
You can use timer in a way like this
Timer timer = new Timer();
If you want your code to run multiple times:
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// Your logic here
// Your logic will run every 60 second
System.out.println("egg hatched");
}
}, 0, 60000);
If you want it to run only one time
timer.schedule(new TimerTask() {
#Override
public void run() {
// Your logic here
System.out.println("egg hatched");
}
}, 60000);
You can read more about class timer in java here
The easiest old-fashioned single thread approach is
Thread.sleep(60*1000);
System.out.println("egg hatched");
And there is no guaranty that it print exactly after minute
System.currentTimeMillis() returns the current time of the system in milliseconds to your. So you need to create a Thread checking for the current time in a while loop an react to it.
Try run it it a separate scheduled thread;
ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
Runnable hatcher = new Runnable() {
#Override
public void run() {
egg.hatch();
}
};
scheduler.schedule(hatcher, 60, TimeUnit.SECONDS);
Is it possible to repeatedly execute a task each day, each minute, each second, each year? I want it to run like a daemon.
I need a scheduled task to search the database continuously; if it finds a certain value then it should execute a further task.
I want to ask whether it is possible to repeatedly
You can use a loop, or a ScheduleExecutorService, or a Timer, or Quartz.
each day each minute each second each year
So once a second.
I want it to run like a daemon.
I would just make it a daemon thread then. No need to make it "like" a daemon.
if it find the correct value then it should do the remaining task.
Simple enough.
Read the data, check the value and if its what you want do the rest.
The java.util.Timer and java.util.TimerTask classes, which I’ll refer to collectively as the Java timer framework, make it easy for programmers to schedule simple tasks.
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");
}
}
OR
Scheduling a Timer Task to Run Repeatedly
int delay = 5000; // delay for 5 sec.
int period = 1000; // repeat every sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
// Task here ...
}
}, delay, period);
In order to do tasks based on time you would want to use threads. Check out this link in order to learn more about them: http://docs.oracle.com/javase/tutorial/essential/concurrency/threads.html
Hmm so the program is going to be running all the time? Might want to look into Java Timer
Perhaps a look at the java.util.Timer or Quartz Scheduler would be helpful.
A ScheduledThreadPoolExecutor might also be helpful. Look into their example code and you should be able to do it.
For my MIDI player, I wanted to print 10 times in a second to get an accuracy of the timing but, the program consume quite a large amount of memory, how do I fix the code?
public void tick(int seconds) {
timer = new Timer();
timer.schedule(new tickcount(), seconds * 100);
}
class tickcount extends TimerTask {
public void run() {
if(sequencer != null) {
System.out.println("sec"+sequencer.getMicrosecondPosition()/1000000);
timer = null;
tick(1);
} else {
timer.cancel();
}
}
}
I don't really see how this code could be causing any kind of large memory consumption, unless it has to do with the incredible rate at which it'll be creating new threads.
At any rate, you should use a ScheduledExecutorService... Timer is kind of outdated (though even using it, you shouldn't be creating a new Timer each time your task runs). If you want the code in your tickcount task to run once every 0.1 seconds, you could do it like this:
private final ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor();
private Future<?> timingTask;
public void tick(long milliseconds) {
timingTask = scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println("sec"+sequencer.getMicrosecondPosition()/1000000);
}
}, 0, milliseconds, TimeUnit.MILLISECONDS);
}
Here, the tick method will start your timer running, calling the Runnable every milliseconds ms, starting immediately. It also assigns a Future<?> to a field... this allows you to call timingTask.cancel(true) to cancel the scheduled task from running prior to setting sequencer to null.
Other than creating Timer object every time in tick() method call use a global timer object instance and reuse it