Repeat something after a specific time interval - java

I have been going through some of the SO questions about doing something after a specific interval of time (like printing hello world every five seconds).
I saw different ways that we can do it in a java program. my question is how java does this internally.
Once we run a java program, the main function starts executing in a thread. But this thread can be sent to Runnable state anytime(pause the execution). So if I had stated the print statement in the main function, how does java keep track of time now. what if the java program was not resumed for the next five seconds?
One way this could work is if we meant "every 5 seconds in the time period which the java program is running" . Is that how the JVM does this?
Assume that I have a single processor.

Ok, lets trace the calls. If we are using ScheduledThreadPoolExecutor we can find that it uses DelayedWorkQueue internally:
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue());
To await next tasks DelayedWorkQueue uses Condition available = lock.newCondition():
available.awaitNanos(delay);
Ok, lets take a look at awaitNanos implementation in AbstractQueuedSynchronizer:
LockSupport.parkNanos(this, nanosTimeout);
And the LockSUpport:
unsafe.park(false, nanos);
This is native method which uses operating systems's scheduler to delay thread execution.

Related

Java Threads, join() taking too long?

So I have some code, I am creating 6 threads, in my main thread, that run some code. I start the threads. I then call join() on the threads, so that the main thread waits for them all to die before continuing with execution.
Now, I am using some really basic and most likely inaccurate way to measure how long my code takes to run. Just calls to get the system time at the start, the end, and then print the difference.
Lets say it is taking, for example, around 500ms to run all of my code.
I decided to remove the calls to join() for each thread, and instead I just told my main thread to sleep for 20ms. This resulted in my code finishing in around 200ms, and the main thread managed to continue with execution with the proper data from the worker threads - i.e. the 6 worker threads must have finished in that 20ms wait.
THEREFORE, why is it taking so much longer when I use .join on each worker thread? Naturally, I cannot keep the call in the main method to sleep(20), and would rather use something like join()'s
The problem with multi-threaded bugs is you can appear to be working when it is not working reliably. It is possible your threads are doing something you don't need at the end, or you joining thread doesn't use the results right away. In any case, I suggest you wait for the result correctly.
BTW I would use an ExecutorService as this allows you to recycle your threads and wait for just the results you need in the form of a Future<MyResult> note this also captures and Exception/Error thrown as well.
It is also possible that your code is simply not getting finished if you take out the joins. If your main function exits without joining on all of its threads, then it is possible some are getting set as daemon threads via setDaemon(), which would stop the program cleanup from waiting on them.
Do you own all the code involved?

can subsequent sleep() be skipped if the thread actually slept too long?

Let's assume that I have a following loop in a Thread (Let's call it Thread-A).
while (threadCondition) {
System.out.println(new Date());
Thread.sleep(1000);
}
and assume that other Thread-B will cause that the application is hanging up of the time >=2sec (because of some other Thread (Let's call it Thread-B, because of not enough CPU resources, low available memory, etc.)
Is it possible that when the Thread-A will come into action after those mentioned >=2 sec then the System.out.println(new Date()) will be executed twice one after another ('instantly', without the sleep), and will print the equal date (with the same number of millis) twice?
JVM does not guarantee the precision of time slept. It may wake after 996ms, 1003ms, or 2000ms - all are valid times
However, these sleep times are not guaranteed to be precise, because
they are limited by the facilities provided by the underlying OS.
Also, the sleep period can be terminated by interrupts, as we'll see
in a later section. In any case, you cannot assume that invoking sleep
will suspend the thread for precisely the time period specified --
source
No track is kept of the amount of time the thread really slept.
When another sleep() is encountered, the thread will wait another (and again, more or less) 1000ms before waking.
Since the sleep time is not precise, it is possible that at time 10.000 your app printed the date once, and at 10.981 it printed the same date again, evn though almost once second has passed.
Also: remember, that the sleep() method may be interrupted. If the exception handling code is in this loop, the sleep may get interrupted, exception swallowed and two dates printed.
Two calls to new Date() can give the same time if
if is in the same milli-second
if they are within the resolution of the clock. e.g. on Windows XP it is ~16 ms.
if time is changed by NTP or similar. e.g. time can go backwards and repeat.
if you use have byte code instrumentation to override the time. e.g. because you want a test driven clock.
if two thread start 2 seconds apart but finish at the same time, they can print the same time.
if thread B starts first and thread A starts after, thread B can print a time after thread A. Just because it starts earlier doesn't mean it will finish first.
new Date() will print the same date if they occur in the same second by default.
No, Thread.sleep(...) delays execution from when it is called for the specified amount of time. There's no internal counter keeping track of "current time" which can become out of sync due to the thread being pushed to the background temporarily, which seems to be what you're thinking.
I don't believe it is possible.
When application is hanging up because of any of the reasons you mentioned, it resumes executing from the line of code it stopped.
The fact that the code cause a hang that now may be redundant is irrelevant. You don't really expect the JVM to analyze your code...
Why not use System.nanoTime() ( ie the high-resolution performance counter in the PC) in place of date(). And if you put the sleep in an if and write the condition correctly it won't sleep the thread.

Re-executing a Java program after a certain delay

I want to execute a Java program in Eclipse multiple times with a certain delay.
I was trying to use ScheduleAtFixedRate() to re-execute the program after a certain interval of time. So what is the main difference between ScheduleAtFixedRate() and ScheduledExecutorService?
What is the advantage of using the latter?
Does it continue running the schedule of execution when the computer is set on a sleep mode?
Provided you mean .scheduleAtFixedRate() (note the little s), then it is a method provided by ScheduledExecutorService. As such, there is no {dis,}advantage to using either.
You can create a ScheduledExecutorService by calling, for instance:
final ScheduledExecutorService service
= Executors.newScheduledThreadPool(...);
service.scheduleAtFixedRate(...);
As to:
Does it continue running the schedule of execution when the computer is set on a sleep mode?
No. It is the OS which puts the computer to sleep, and it is the OS which you should instruct to wake up at the time(s) you want. A running Java program is a JVM is a process is ultimately controlled by the OS.
ScheduledExecutorService is an interface that defines the behaviour of a task executor and ScheduleAtFixedRate() is method of this interface which expects the implementation class i.e the executor to execute the input task at fixed interval.
When your computer goes to sleep or hibernates nothing will execute.

How to get threads with loops running concurrently to work with Thread.yield()?

I have the following situation. I have an application that runs mostly on one thread. It has grown large, so I would like to run a watchdog thread that gets called whenever the main thread changes into a different block of code / method / class so I can see there is "movement" in the code. If the watchdog gets called by the same area for more than a second or a few, it shall set a volatile boolean that the main thread reads at the next checkpoint and terminate / restart.
Now the problem is getting either of the threads to run somewhat at the same time. As soon as the main thread is running, it will not let the watchdog timer count properly. I was therefore thinking of yielding every time it calls the watchdog (so it could calculate time passed and set the value) but to no avail. Using Thread.sleep(1) instead of Thread.yield() works. But I don't want to have several areas of code just wasting calculation time, I am sure I am not doing it the way it is meant to be used.
Here a very simple example of how I would use Thread.yield(). I do not understand why the Threads here will not switch (they do, after a "long" and largely unpredictable time). Please give me an advice on how to make this simple example output ONE and TWO after each other. Like written before, if I switch yield() with sleep(1), it will work just like I'd need it to (in spite of waiting senselessly).
Runnable run1 = new Runnable(){
public void run(){
while(true){
System.out.println("ONE");
Thread.yield();
}
}
};
Runnable run2 = new Runnable(){
public void run(){
while(true){
System.out.println("TWO");
Thread.yield();
}
}
};
Thread tr1 = new Thread(run1);
Thread tr2 = new Thread(run2);
tr1.start();
tr2.start();
Thread.yield()
This static method is essentially used to notify the system that the
current thread is willing to "give up the CPU" for a while. The
general idea is that:
The thread scheduler will select a different thread to run instead of
the current one.
However, the details of how yielding is implemented by the thread
scheduler differ from platform to platform. In general, you shouldn't
rely on it behaving in a particular way. Things that differ include:
when, after yielding, the thread will get an opportunity to run again;
whether or not the thread foregoes its remaining quantum.
The take away is this behavior is pretty much optional and not guaranteed to actually do anything deterministically.
What you are trying to do is serialize the output of two threads in your example and synchronize the output in your stated problem ( which is a different problem ), and that will require some sort of lock or mutex to block the second thread until the first thread is done, which kind of defeats the point of concurrency which is usually the reason threads are used.
Solution
What you really want is a shared piece of data for a flag status that the second thread can react to the first thread changing. Preferably and event driven message passing pattern would be even easier to implement in a concurrently safe manner.
The second thread would be spawned by the first thread and a method called on it to increment the counter for which block it is in, you would just use pure message passing and pass in a state flag Enum or some other notification of a state change.
What you don't want to do is do any kind of polling. Make it event driven and just have the second thread running always and checking the state of its instance variable that gets set by the parent thread.
I do not understand why the Threads here will not switch (they do, after a "long" and largely unpredictable time). Please give me an advice on how to make this simple example output ONE and TWO after each other. Like written before, if I switch yield() with sleep(1), it will work just like I'd need it to (in spite of waiting senselessly).
I think this is more about the difference between ~1000 println calls in a second (when you use sleep(1)) and many, many more without the sleep. I think the Thread is actually yielding but it may be that it is on a multiple processor box so the yield is effectively a no-op.
So what you are seeing is purely a race condition high volume blast to System.out. If you ran this for a minute with the results going to a file I think you'd see a similar number of "ONE" and "TWO" messages in the output. Even if you removed the yield() you would see this behavior.
I just ran a quick trial with your code sending the output to /tmp/x. The program with yield() ran for 5 seconds, generated 1.9m/483k lines, with the output sort | uniq -c of:
243152 ONE
240409 TWO
This means that each thread is generating upwards of 40,000 lines/second. Then I removed the yield() statements and I got just about the same results with different counts of lines like you'd expect with the race conditions -- but the same order of magnitude.

Java Timer and scheduleAtFixedRate + System Suspend

I am working on a Java program and using Timer objects to run tasks every few minutes or hours. This works fine in normal operations, but I am running into a problem with "Sleep mode" on Mac (maybe on other OSes, but I haven't tried yet).
Consider this code sample:
//Setup the timer to fire the ping worker (every 3 minutes)
_PingTimer.scheduleAtFixedRate(new TimerTask(){
public void run(){
Program.PingThread = new PingWorker(Settings.Username, Settings.UserHash, true, true);
Program.PingThread.CheckOpenPort = true;
Program.SwingExecutor.execute(Program.PingThread);
}
}, 0, 180000);
In normal operation this would fire every 3 minutes with enough accuracy (I'm not concerned about the exact second or anything). The problem with this is after sleeping the computer for a few hours or so it seems to just BLAST the system with backlogged timer requests.
It seems to be running all of the missed timer hits during sleep at once trying to make up for lost time.
Is there a way i can prevent this? I tried using synchronized and some other thread techniques, but this only ensures that they aren't all running at the same time. They still continue to run one after another until the backlog is passed.
Thanks for any help you can provide!
Have you looked at the API? It clearly states the following:
In fixed-rate execution, each
execution is scheduled relative to the
scheduled execution time of the
initial execution. If an execution is
delayed for any reason (such as
garbage collection or other background
activity), two or more executions will
occur in rapid succession to "catch
up." In the long run, the frequency of
execution will be exactly the
reciprocal of the specified period
(assuming the system clock underlying
Object.wait(long) is accurate).
This is one reason why you should consider using a ScheduledExecutorService. This link may also prove useful.
Use schedule instead of scheduleAtFixedRate.

Categories