I have a requirement of writing a daemon which initiates number of threads that wakes up at different times. The daemon is written in Java using commons apache library and is run on a Linux machine (Fedora 13 ).
One thread wakes up everyday to perform task A which happens as scheduled.
But there is another thread which is scheduled to wake up every Monday at 6 am to perform some task which does not happen as scheduled. The problem is that this thread wakes up much before the actual scheduled time. It runs 2 days after the completion of the previous run though it should run only after a week. The waiting time is calculated correctly using our own timer class and because this reuses existing code i do not see a problem in this.
What could be the problem here?
Thanks
Thread.sleep() doesn't make any guarantees, and it might wake up earlier than expected. you should always use it in the loop:
long curTime = System.currentTimeMillis();
while (wakeUpTime - curTime > 0) {
try {
Thread.sleep(wakeUpTime - curTime);
} catch (InterruptedException ex) { }
curTime = System.currentTimeMillis();
}
Related
This question already has answers here:
How to start two process at the same time and then wait both completed?
(3 answers)
Closed 1 year ago.
I'm writing a small program which is supposed to update Firmware on Servers. The way I currently do this is by issuing a command via the ProcessBuilder, executing it and using exitCode = process.waitFor(); to wait until the command is finished.
Some of these Firmware updates can take a few minutes, so when setting up multiple Systems, these Firmware updates can take hours, if done separately.
I have tried creating Threads, while using CyclicBarrier, to ensure that all Firmware Updates are started at the same time. (See: Stackoverflow-Question: How to start two threads at “exactly” the same time
The problem I have spotted with this however, that my program will continue as usual after starting all the threads - which in this case would be to reboot all the systems, which might break them if they are still in the process of updating Firmware.
How could I ensure that all Firmware Updates are done before continuing? I have thought about letting the program sleep for 10-15 minutes, but would like a more reliable approach.
You may use a CountDownLatch in addition to the barrier. Pass the CountDownLatch to each of the thread, once the firmware update is completed, just call the count-down on the latch. In your main thread, after starting all the threads, you may wait by calling latch.await and it will wail till all the other threads finish. You may find a sample here.
You can even use a CountDownLatch with 1 as the count for the starting gun in your case, which precludes the use of the CyclicBarrier.
You need Thread.join() method. Take a look at the example:
public static void main(String[] args) throws InterruptedException {
Runnable sleepTwoSeconds = () -> {
try {
Thread.sleep(2000);
System.out.println("Sleeping finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread t1 = new Thread(sleepTwoSeconds);
t1.start();
Thread t2 = new Thread(sleepTwoSeconds);
t2.start();
t1.join();
t2.join();
System.out.println("Main thread continue.");
}
"How could I ensure that all Firmware Updates are done before continuing?" Main thread will not continue until t1 and t2 are done.
I just stumbled upon a weird behavior of daemon threads which I can't explain. I've reduced my code to a minimal, complete and verifiable sample:
public static void main(String[] args) throws InterruptedException {
Thread runner = new Thread(() -> {
final int SIZE = 350_000;
for (int i = 0; i < SIZE; i++) {
for (int j = i + 1; j < SIZE; j++) {
if (i*j == SIZE * SIZE - 1) {
return;
}
}
}
});
runner.setDaemon(true);
runner.start();
// Thread.sleep(1000);
System.out.println("Exiting.");
}
The code executed by the runner thread takes about 12 secs to terminate on my box, and we're not interested in what it does, since I just needed to spend some time computing.
If this snippet is run as it is, it works as expected: it terminates just after its start.
If I uncomment the Thread.sleep(1000) line and run the program, it works for about 12 seconds, then prints out "Exiting" and terminates.
As far as I understood how daemon threads work, I expected this code to run for 1 second and then to terminate execution, since the only user thread running is the one launched with the main() method (the runner is a background daemon thread) and as soon as the 1000 msec are passed, it reaches the end of its execution and the JVM should stop. Also, it looks quite strange that "Exiting" is printed only after 12 seconds, and not when the program starts.
Am I wrong? How can I achieve the desired behavior (pause for a second and then stop, independently from what the runner thread is doing)?
I'm using a 64bit Oracle JDK 1.8.0_112 on a linux box and it has the same behavior either if launched from an IDE or from the command line.
Thanks,
Andrea
This is maybe a consequence of counted loop optimization which removed safepoint polls from your nested loops. Try to add -XX:+UseCountedLoopSafepoint flag to your JVM startup options.
Thread#sleep(long) pauses the main thread before it returns from its main method (i.e. before the JVM is considering the program done as long as no non-deamon threads are alive). The scheduler is then free to run any other runnable thread which would be the deamon thread. As it stands, there is no apparent reason for the JVM to forcibly preempt the deamon thread before it finishes execution to continue in the main thread (is it's done sleeping yet), so the JVM is free to continue its schedule. However, it may at any time elect to pause the running thread and schedule another runnable thread for execution, so reproducibility is not guaranteed for your example.
You can force a preemption by inserting calls to Thread#yield() or #sleep(1) in the loops. I bet you'll start seeing the snippet exiting faster and before it finishes the loops.
There's more to learn about Thread states and scheduling, a nice overview can be found here.
Update for comment:
I cannot modify the code in the background thread (is a requirement), so I was looking for a way to stop it if it takes too long (a description of what I'm doing is stackoverflow.com/questions/41226054/… ).
It's legally only possible to stop a running thread from within, so you usually have it test an abort condition every iteration, and if the condition is met, the run method return;s. An abort condition could be as simple as a boolean flag that is set from the outside (! volatile caveat !). So the dead-simplest solution would be to have the main thread set such a flag after the sleep.
Another possibility might be using an ExecutorService that supports timeouts, see this Q&A for an example involving ScheduledExecutorService.
Still I don't understand how the scheduler can decide to wait for 12 seconds before running the System.out instruction.
It does not wait 12 seconds, it let's the deamon thread run to completion because being a deamon only matters to the JVM when deciding if it's safe to halt the JVM. For the scheduler, only the state of the thread matters and as far as it's concernced, after the 1s sleep of the main thread, it has a running (deamon) and a runnable thread (main), and no indication that the running thread should be paused in favor for the runnable thread. Switching threads is also expensive computationally, so the scheduler might be reluctant lacking any indication. An indication to switch might be sleeps and yields, but also GC runs and a whole lot of other things.
I have a Timer class that I want to schedule to run for 30 minutes and for it to execute every hour from Saturday at 12AM to Sunday at midnight.
How would I go about doing this?
Thanks.
The java.util.Timer class does not have the functionality to do this using repeated tasks:
You cannot configure a Timer to >>stop<< running repeated tasks at a given time
The execution model for repeated tasks is "fixed-delay execution"; i.e. a new task is scheduled based on the end-point of the previous task. That results in time slippage ... if tasks take a long time.
The simple solution is:
create a single Timer object
use schedule(TimerTask task, Date time) in a loop to schedule 48 separate tasks, starting on each hour in the range that you require.
According to the javadoc, Timer is scalable and should be able to cope with lots of scheduled tasks efficiently.
The above does not deal with the requirement that each task runs for 30 minutes. It is not clear what that actually means, but if you want the task to run for no more than 30 minutes, then you need to implement a "watch dog" that interrupts the thread running the task when its time is up. The task needs to be implemented to check for and/or handle thread interrupts appropriately.
You could have a loop run and in the loop just sleep for an hour or however long you wanted. Would something like this work?
for(int i = 0; i < 24; i++) {
// do whatever you want to do
try {
// Sleep for an hour
Thread.sleep(6000000);
catch(InterruptedException e) {
e.printStackTrace();
}
}
I might have misunderstood the question... but if that's what you wanted.. then... yay?
I want to make my thread to wait for 30 minutes. Are there any problems of doing this?
You can make your thread sleep for 30 minutes like this:
Thread.sleep(30 * // minutes to sleep
60 * // seconds to a minute
1000); // milliseconds to a second
Using Thread.sleep is not inherently bad. Simply explained, it just tells the thread scheduler to preempt the thread. Thread.sleep is bad when it is incorrectly used.
Sleeping without releasing (shared) resources: If your thread is sleeping with an open database connection from a shared connection pool, or a large number of referenced objects in memory, other threads cannot use these resources. These resources are wasted as long as the thread sleeps.
Used to prevent race conditions: Sometimes you may be able to practically solve a race condition by introducing a sleep. But this is not a guaranteed way. Use a mutex. See Is there a Mutex in Java?
As a guaranteed timer: The sleep time of Thread.sleep is not guaranteed. It could return prematurely with an InterruptedException. Or it could oversleep.
From documentation:
public static void sleep(long millis) throws InterruptedException
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.
You could also use, as kozla13 has shown in their comment:
TimeUnit.MINUTES.sleep(30);
The answer of Krumia already perfectly shows how to sleep a running Thread. Sometimes, the requirement to sleep or pause a thread originates from the wish to perform an operation at a later date. If that's the case, you should better use a higher level concept like Timer or ScheduledExecutorService:
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.schedule(operation, 30, TimeUnit.MINUTES);
Where operation is the Runnable you want to execute in 30 minutes.
Using a ScheduledExecutorService, you can also execute operations periodically:
// start in 10 minutes to run the operation every 30 minutes
executor.scheduleAtFixedDelay(operation, 10, 30, TimeUnit.MINUTES);
I have the following code:
public Move chooseMove(Board board) {
// start parallel thread
this.tn = new TreeNode(this.myboard, this, null);
tn.stop = false;
this.curT = (new Thread(tn));
this.curT.start();
try {
long startTime = System.currentTimeMillis();
Thread.sleep(4000 );
System.out.println(System.currentTimeMillis() - startTime);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
tn.stop=true;
return getBestMove();
}
}
The output is sometimes a value that is way greater than 4000ms like 5400ms which means that the thread is sleeping more than it should. Any help?
Thanks.
EDIT:
I understand that there is NO guarantee of Thread#sleep stoping precisely after the specified delay. However, an additional 1400ms is a long delay. Basically,I am implementing a game player agent and I need a way to run a task and then return a value to the server after 5s (or else the server ends the game). The server is using java.util.Timer.schedule(TimerTask task, long delay). There is only one thread running concurent to the main thread which is this.curT in the code above, so there is ins't really heavy multithreading.
From docs.oracle.com:
Two overloaded versions of sleep are provided: one that specifies the sleep time to the millisecond and one that specifies the sleep time to the nanosecond. 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.
This is common behavior and it is described in Thread#sleep javadoc:
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.
Based on this, there's no guarantee of Thread#sleep stoping the work of the thread by the amount of milliseconds stated in the parameter.
Thread#sleep will make your thread sleep for exactly 4 seconds and then wake up.
Once your thread has woken up the OS scheduler places it in the runnable queue.
When it is next picked by the scheduler it will become a running thread i.e. will occupy the CPU.
So there is an additional delay overhead due to the OS scheduler which can vary per OS, system load etc. This is unrelated to Java