How to use the current time in a Java Program? - java

Say, for example, I want to run the following program
double x = 15.6
System.out.println(x);
But I wanted to repeat the program until a certain time has elapsed, such as the following:
do{
double x = 15.6
System.out.println(x);
}while (current time is earlier than 12.00pm)
Even though the example is completely hypothetical, how would I make that do while loop so that the program would keep running over and over again until a certain time, say 3pm, or9.30pm.
If this is not possible, is there any way I can simulate this, by running the program every so many seconds, until that time has been reached?

a) You usually don't need the code to actually run until a time has come - you wouldn't have any control over the amount of times the code executed this way. Regular code has to sleep sometimes, to give control to OS and other processes so that they don't clog the system with 100% CPU load. As such, actually running the code constantly is a wrong approach to 99% of the possible problems related to timings. Please describe the exact problem you want to solve using this code.
b) For those 99% of problems, use a Timer instance. Simple as that. https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html - schedule the task to run e.g. 1000 times a second, and check the time in each event, terminating the Timer instance when the time threshold has been exceeded.
For example, this code above will give you continuous execution of Do something part, every 1 second, until 16.11.2014 20:00 GMT. By changing delayMs you can easily achieve higher/lower time granularity. If you expect your code to be run more often than 1000/sec, you should probably use JNI anyway, since Java timers/clocks are known to have <10ms granularity on some (older) platforms, see How can I measure time with microsecond precision in Java? etc.
Timer timer = new Timer();
int delayMs = 1000; // check time every one second
long timeToStop;
try {
timeToStop = new SimpleDateFormat( "DD.MM.YYYY HH:mm" ).parse( "16.11.2014 20:00" ).getTime(); // GMT time, needs to be offset by TZ
} catch (ParseException ex) {
throw new RuntimeException( ex );
}
timer.scheduleAtFixedRate( new TimerTask() {
#Override
public void run() {
if ( System.currentTimeMillis() < timeToStop ) {
System.out.println( "Do something every " + delayMs + " milliseconds" );
} else {
timer.cancel();
}
}
}, 0, delayMs );
or you can use e.g. ExecutorService service = Executors.newSingleThreadExecutor(); etc. - but it's virtually impossible to give you a good way to solve your problem without explicitly knowing what the problem is.

Something like this
//get a Date object for the time to stop, then get milliseconds
long timeToStop = new SimpleDateFormat("DD:MM:HH:mm").parse("16:11:12:00").getTime();
//get milliseconds now, and compare to milliseconds from before
do {
//do stuff
} while(System.currentTimeMillis() < timeToStop)

Related

What is the most efficient way to simulate a countdown in java?

I want to print to the console every second. So far, I've been able to think of two ways to do this.
long start_time = System.currentTimeMillis();
while(true){
if ((System.currentTimeMillis() - start_time) >= 1000) {
System.out.println("One second passed");
start_time = System.currentTimeMillis();
}
}
And this
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("One second passed");
}
Is any method safer or more reliable or more efficient than the other?
or maybe there are use cases for each?
Thanks
This is not as simple as it seems.
The problem with your solutions are that the first is very inefficient, and the second is liable to drift because sleep(1000) does not guarantee to sleep for exactly 1 second. (The javadoc says that sleep(1000) sleeps for at least one second.)
One possibility is to use ScheduledExecutorService.scheduleWithFixedDelay and compute the delay each time by looking at the difference between the millisecond clock and your start time (or end time). That will keep your messages in sync with real time (more or less).
Or maybe you can simplify that using scheduleAtFixedRate, because it looks like ScheduledThreadPoolExecutor will take care of the clock syncing problem.
Another possibility is to look for a 3rd-party library that implements a "cron-like" scheduler in Java.

What is the point of Apache Lang3 StopWatch.split()?

I am currently evaluating implementations between Apache StopWatch and Guava's Stopwatch and the split functionality in the former intrigued me, but I am struggling to understand what exactly it does, and what value it has.
According to the documentation for StopWatch: https://commons.apache.org/proper/commons-lang/javadocs/api-3.9/org/apache/commons/lang3/time/StopWatch.html
split() the watch to get the time whilst the watch continues in the background. unsplit() will remove the effect of the split. At this point, these three options are available again.
And I found some examples, such as this, which offer very little, since it appears split is just cumulative. The page says the method is for "splitting the time", which I figured as much based on the method, but the page makes no mention to what that actually means. It would even appear that this example is utterly wrong, because the docs suggest that you should unsplit before you split again.
I initially thought it was for the following usecase:
StopWatch stopwatch = StopWatch.createStarted();
do something for 5 seconds
stopwatch.split();
do something for 10 seconds
stopwatch.stop();
System.out.println(stopwatch.getTime());
System.out.println(stopwatch.getSplitTime());
I thought that stopwatch total time would read as 15 seconds, and stopwatch split time would read as either 10 or 5 seconds, but it appears that both methods output 15 seconds.
Next, I thought maybe the split value is a delta you can take, and then remove from the total timer, something like:
StopWatch stopwatch = StopWatch.createStarted();
do something for 5 seconds
stopwatch.split();
do something for 10 seconds
stopwatch.unsplit();
stopwatch.stop();
System.out.println(stopwatch.getTime());
// System.out.println(stopwatch.getSplitTime()); errors because of unsplit
My thought here was that the split time would be 10 seconds, and when unsplit from the main timer, the main timer would read as 5 seconds... but this seems no different from a suspend() call... I also tried this, and the timings remain the same nonetheless for me.
Am I missing something here, or is my interpretation of what this is supposed to do all wrong?
This is the source code for getSplitTime() (it calls this other function internally):
public long getSplitNanoTime() {
if (this.splitState != SplitState.SPLIT) {
throw new IllegalStateException("Stopwatch must be split to get the split time. ");
}
return this.stopTime - this.startTime;
}
So it will return stopTime-startTime. Beware of stopTime. It's the liar that's confusing you.
This is the code for stop():
public void stop() {
if (this.runningState != State.RUNNING && this.runningState != State.SUSPENDED) {
throw new IllegalStateException("Stopwatch is not running. ");
}
if (this.runningState == State.RUNNING)
{
//is this the same stopTime getSplitTime uses? yep, it is
this.stopTime = System.nanoTime();
}
this.runningState = State.STOPPED;
}
What's happenning then?
Calling stop() updates the stopTime variable and makes the stopwatch "forget" the last time it was splitted.
Both split() and stop() modify the same variable, stopTime, which is overrided when you call stop() at the end of your process.
Although sharing the same variable may look wierd, it really makes sense, as an splittedTime of an StopWatch should never be bigger than the total elapsed time. So it's a game regarding the order of the functions executed in the StopWatch.
This is the code for split(), in order to see that both methods do use stopTime:
public void split() {
if (this.runningState != State.RUNNING) {
throw new IllegalStateException("Stopwatch is not running. ");
}
this.stopTime = System.nanoTime(); // you again little f..
this.splitState = SplitState.SPLIT;
}
That's why this little adorable Apache liar shows you 15 seconds on the splittedTime: because stop() updated the stopTime variable getSplitTime() will use to return its value. (the first code snippet)
Note the simplicity of the split() function (this also barely answers OP's question). It is responsible of:
Checking wether the StopWatch is running.
Marking a new stopTime.
Setting the splitState to SPLIT.
TLDR lol
Calling getSplitTime() before stopping the StopWatch should show you the desired value:
stopTime won't be updated by stop() yet.
The returning value will now match the time elapsed between the last split() and the startTime.
Some examples: (yes, editing at saturday night cause I need a social life)
StopWatch stopwatch = StopWatch.createStarted();
do something for 5 seconds
stopwatch.split(); //stopTime is updated [by split()]
System.out.println(stopwatch.getSplitTime()); // will show 5 seconds
do something for 10 seconds
System.out.println(stopwatch.getSplitTime()); // will also show 5 seconds
stopwatch.stop(); //stopTime is updated again [by stop()]
System.out.println(stopwatch.getTime()); // 15s
System.out.println(stopwatch.getSplitTime()); // 15s
Another one:
StopWatch stopwatch = StopWatch.createStarted();
do something for 5 seconds
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 5s
do something for 10 seconds
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 15s
do something for 1 second
stopwatch.stop();
System.out.println(stopwatch.getTime()); // 16s
And a last one. Mocked the time with sleeps, just for the fun, you know. I was so bored I really imported the apache jar in order to test this locally:
StopWatch stopwatch = StopWatch.createStarted();
Thread.sleep(5000);
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 5s
Thread.sleep(10000);
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 15s
stopwatch.reset(); // allows the stopWatch to be started again
stopwatch.start(); // updates startTime
Thread.sleep(2000);
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 2s
Thread.sleep(1000);
stopwatch.stop();
System.out.println(stopwatch.getTime()); // 3s
System.out.println(stopwatch.getSplitTime()); // 3s
//it was so fun putting the sleeps
Note that calling getSplitTime() on an stopped Watch won't throw any exception, because the method will only check wheter the splitState is SPLIT.
The confusion may be caused by these two facts:
The code allows you to stop() regardless of the SplitState, making your last split() futile without you being aware. Futile, I love that word. Had to include it in my answer somehow. Futileeee
It also allows you to check the splittedTime on an stopped watch (if it is still on SPLIT state), when it really just will return the total elapsed time between the last start() and the stopping time. (little liar)
In this scenario, where the stopwatch is stopped and splitted at the same time, getTime() and getSplitTime() will always show the same value when called after stop().
[Personal and subjective opinion]
Let's say you have a Counters class with different variables to check elapsed times. You also want to output the total elapsed time for each operation, every 60 seconds . In this example, counters is an instance of a Counters class that owns two long variables: fileTime and sendTime, that will accumulate the elapsed time within each operation during an specific interval (60s). This is just an example that assumes each iteration takes less than 1000 ms (so it will always show 60 seconds on the elapsed time):
long statsTimer = System.currentTimeMillis();
while (mustWork)
{
long elapsedStatsTimer = System.currentTimeMillis()-statsTimer; //hits 60185
if (elapsedStatsTimer > 60000)
{
//counters.showTimes()
System.out.println("Showing elapsed times for the last "+
(elapsedStatsTimer/1000)+ " secs"); //(60185/1000) - 60 secs
System.out.println("Files time: "+counters.fileTime+" ms"); //23695 ms
System.out.println("Send time : "+counters.sendTime+" ms"); //36280 ms
long workTime = counters.sendTime+counters.fileTime;
System.out.println("Work time : "+workTime+" ms"); //59975 ms
System.out.println("Others : "+(elapsedStatsTimer-workTime)+" ms"); //210 ms
//counters.reset()
counters.fileTime=0;
counters.sendTime=0;
statsTimer= System.currentTimeMillis();
}
long timer = System.currentTimeMillis();
//do something with a file
counters.fileTime+=System.currentTimeMillis-timer;
timer = System.currentTimeMillis();
//send a message
counters.sendTime+=System.currentTimeMillis()-timer;
}
That Counters class could implement the reset() and showTimes() functions, in order to clean up the code above. It could also manage the elapsedStatsTimer variable. This is just an example to simplify its behaviour.
For this use case, in which you need to measure different operations persistently, I think this way is easier to use and seems to have a similar performance, as the StopWatch internally makes the exact same thing. But hey, it's just my way to do it : ).
I will accept downvotes for this opinion in an honorable and futile way.
I would love to finish with a minute of silence in honour of unsplit(), which may be one of the most irrelevant methods ever existed.
[/Personal and subjective opinion]
Just noticed TLDR section is actually bigger than the previous section :_ )

Why is a particular Guava Stopwatch.elapsed() call much later than others? (output in post)

I am working on a small game project and want to track time in order to process physics. After scrolling through different approaches, at first I had decided to use Java's Instant and Duration classes and now switched over to Guava's Stopwatch implementation, however, in my snippet, both of those approaches have a big gap at the second call of runtime.elapsed(). That doesn't seem like a big problem in the long run, but why does that happen?
I have tried running the code below as both in focus and as a Thread, in Windows and in Linux (Ubuntu 18.04) and the result stays the same - the exact values differ, but the gap occurs. I am using the IntelliJ IDEA environment with JDK 11.
Snippet from Main:
public static void main(String[] args) {
MassObject[] planets = {
new Spaceship(10, 0, 6378000)
};
planets[0].run();
}
This is part of my class MassObject extends Thread:
public void run() {
// I am using StringBuilder to eliminate flushing delays.
StringBuilder output = new StringBuilder();
Stopwatch runtime = Stopwatch.createStarted();
// massObjectList = static List<MassObject>;
for (MassObject b : massObjectList) {
if(b!=this) calculateGravity(this, b);
}
for (int i = 0; i < 10; i++) {
output.append(runtime.elapsed().getNano()).append("\n");
}
System.out.println(output);
}
Stdout:
30700
1807000
1808900
1811600
1812400
1813300
1830200
1833200
1834500
1835500
Thanks for your help.
You're calling Duration.getNano() on the Duration returned by elapsed(), which isn't what you want.
The internal representation of a Duration is a number of seconds plus a nano offset for whatever additional fraction of a whole second there is in the duration. Duration.getNano() returns that nano offset, and should almost never be called unless you're also calling Duration.getSeconds().
The method you probably want to be calling is toNanos(), which converts the whole duration to a number of nanoseconds.
Edit: In this case that doesn't explain what you're seeing because it does appear that the nano offsets being printed are probably all within the same second, but it's still the case that you shouldn't be using getNano().
The actual issue is probably some combination of classloading or extra work that has to happen during the first call, and/or JIT improving performance of future calls (though I don't think looping 10 times is necessarily enough that you'd see much of any change from JIT).

Java - repeatedly run a function in a given number of milliseconds accurately?

Does anyone have a Fairly effective way of running a function repetitively in a precise and accurate number of milliseconds. I have tried to accomplish this by using the code below to try to run a function called wave() once a second for 30 seconds:
startTime = System.nanoTime();
wholeTime = System.nanoTime();
while (loop) {
if (startTime >= time2) {
startTime = System.nanoTime();
wave();
sec++;
}
if (sec == 30) {
loop = false;
endTime = System.nanoTime();
System.out.println(wholeTime - System.nanoTime());
}
}
}
This code did not work and am wondering why this code didn't work and if their is a better approach to the problem. Any ideas on how to improve fix the above code or other successful ways of accomplishing the problem are all welcome. Thank you for your help!
more simple:
long start=System.currentTimeMillis(); // Not very very accurate
while (System.currentTimeMillis()-start<30000)
{
wave();
// count something
}
You can use a Timer+TimerTask: https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html
https://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html
http://bioportal.weizmann.ac.il/course/prog2/tutorial/essential/threads/timer.html
You may use Thread.sleep():
public static void main (String[] args) throws InterruptedException {
int count = 30;
long start = System.currentTimeMillis();
for(int i=0; i<count; i++) {
wave();
// how many milliseconds till the end of the second?
long sleep = start+(i+1)*1000-System.currentTimeMillis();
if(sleep > 0) // condition might be false if wave() runs longer than second
Thread.sleep(sleep);
}
}
Does anyone have a Fairly effective way of running a function repetitively in a precise and accurate number of milliseconds.
There is no way to do this kind of thing reliably and accurately in standard Java. The problem is that there is no way that you can guarantee that your thread will run when you want ti to run. For example:
your thread could be suspended to allow the GC to run
your thread could be preempted to allow another thread in your application to run
your thread could be suspended by the OS while it fetches pages by the JVM back from disk.
You can only get reliable behavior for this kind of code if you run on a hard realtime OS, and an realtime Java.
Note that this is not an issue with clock accuracy. The real problem is that the scheduler does not give you the kind of guarantees you need. For instance, none of the "sleep until X" functionality in a JVM can guarantee that your thread will wake up at time X exactly ... for any useful meaning of "exactly".
The other answers suggest various ways to do this, but beware that they are not (and cannot be) reliable and accurate in all circumstances .. or even on a typical machine running other things as well as your application.

Java thread sleep() method

I am doing a past exam paper of Java, I am confused about one question listed below:
What would happen when a thread executes the following statement in its run() method? (Choose all that apply.)
sleep(500);
A. It is going to stop execution, and start executing exactly 500 milliseconds later.
B. It is going to stop execution, and start executing again not earlier than 500 milliseconds later.
C. It is going to result in a compiler error because you cannot call the sleep(…) method inside the run() method.
D. It is going to result in a compiler error because the sleep(…) method does not take any argument.
I select A,B. but the key answer is only B, does there exist any circumstances that A could also happen? Could anyone please clarify that for me? Many thanks.
I select A,B. but the key answer is only B, does there exist any circumstances that A could also happen? Could anyone please clarify that for me?
Yes, depending on your application, you certainly might get 500ms of sleep time and not a nanosecond more.
However, the reason why B is the better answer is that there are no guarantees about when any thread will be run again. You could have an application with a large number of CPU bound threads. Even though the slept thread is now able to be run, it might not get any cycles for a significant period of time. The precise sleep time also depends highly on the particulars of the OS thread scheduler and clock accuracy. Your application also may also have to compete with other applications on the same system which may delay its continued execution.
For example, this following program on my extremely fast 8xi7 CPU Macbook Pro shows a max-sleep of 604ms:
public class MaxSleep {
public static void main(String[] args) throws Exception {
final AtomicLong maxSleep = new AtomicLong(0);
ExecutorService threadPool = Executors.newCachedThreadPool();
// fork 1000 threads
for (int i = 0; i < 1000; i++) {
threadPool.submit(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
long total = 0;
// spin doing something that eats CPU
for (int j = 0; j < 10000000; j++) {
total += j;
}
// this IO is the real time sink though
System.out.println("total = " + total);
try {
long before = System.currentTimeMillis();
Thread.sleep(500);
long diff = System.currentTimeMillis() - before;
// update the max value
while (true) {
long max = maxSleep.get();
if (diff <= max) {
break;
}
if (maxSleep.compareAndSet(max, diff)) {
break;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
threadPool.shutdown();
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
System.out.println("max sleep ms = " + maxSleep);
}
}
JVM cannot guarantee exactly 500 ms but it will start on or after ~500 ms as it will need to start its 'engine' back considering no other threads are blocking any resources which may delay a bit.
Read: Inside the Hotspot VM: Clocks, Timers and Scheduling Events
Edit: As Gray pointed out in the comment - the scheduling with other threads also a factor, swapping from one to another may cost some time.
According to Javadoc:-
Sleep()
Causes the currently executing thread to sleep (temporarily cease
execution) for the specified number of milliseconds, subject to the
precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors.
So it may be ~500ms
B. It is going to stop execution, and start executing again not earlier than 500 milliseconds later.
Looks more prominent.
As you know that there are two very closely-related states in Thread : Running and Runnable.
Running : means currently executing thread. Its execution is currently going on.
Runnable : means thread is ready to get processed or executed. But is waiting to be picked up by Thread Schedular. Now this thread schedular, as per its own wish/defined algorithm depending upon the JVM(for example, slicing algorithm) will pick up one of the available/Runnable threads to process them.
So whenever you call sleep method, it only guarantees that the execution of the code by the thread which it ran on, is paused for the specified milliseconds in the argument(e.g. 300ms in threadRef.sleep(300);). As soon as the time defined goes by, it comes back to Runnable state(means back to Available State to be picked up by Thread Schedular).
Therefore, there is no guarantee that your remaining code will start getting executed immediately after sleep method completion.
These sleep times are not guaranteed to be precise, because they are limited by the facilities provided by the underlying OS. Option B: Not earlier than 500 is more correct.
You cannot select A and B as they are opposite to each other, the main difference: exactly 500 milliseconds later and not earlier than 500 milliseconds later
first mean exactly what it means (500 milliseconds only), second means that it can sleep 501 or 502 or even 50000000000000
next question - why B is true, it is not so simply question, you need to understand what is the different between hard-realtime and soft-realtime, and explaining of all reasons is quite offtopic, so simply answer - because of many technical reasons java cannot guarantee hard real time execution of your code, this is why it stated that sleep will finish not earlier than ...
you can read about thread scheduling, priorities, garbage collection, preemptive multitasking - all these are related to this

Categories