Java - use wait() method until specific time reached
Solution 1
So this question is, how can I use wait
to act like sleep
. If you want to use wait, you will have to use two threads. Use a ScheduledExecutorService
(Tutorial).
ScheduledExecutorService executor = newSingleThreadScheduledExecutor();
This can be done once and reused. Otherwise you have to shutdown the executor.
We'll set our deadline to be x
minutes in the future, using Instant
from the modern java.time framework (Tutorial).
final Instant deadline = Instant.now().plus(x, ChronoUnit.MINUTES);
Next we want to schedule a task so that our thread will wake in x minutes.
while(Instant.now().isBefore(deadline)){
synchronized(deadline){
executor.schedule(
()->{
synchronized(deadline){
deadline.notifyAll();
}
},
Duration.between(Instant.now(),deadline).toMillis(),
TimeUnit.MILLISECONDS
);
deadline.wait();
}
}
It is in a loop, just in case there is a spurious awake. It resubmits the task, just in case there was a spurious awake and in the meantime the other task completed and didn't wake the thread before the thread called wait again.
This above is a bit tongue in cheek. Really if you just used the following it would seem more ''realtime''.
long diff = deadline.getTimeInMillis()-now.getTimeInMillis();
if(diff>0)
Thread.sleep(diff);
Solution 2
From oracle documentation page
public final void wait(long timeout)
throws InterruptedException
Causes the current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed.
Precondition: The current thread must own this object's monitor.
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}
marcuthh
BEng Software Engineering student and Sheffield Hallam University, currently searching for a work placement for around the time of the next academic year. C# is my specialty, although I'm proficient in other object-oriented languages such as C++ and Java. Currently working on my web design and development and have a solid level of knowledge in HTML, CSS, PHP, SQL, JavaScript and jQuery. Keen to keep learning so I do ask a lot of questions. Love the researching and testing side of things so always happy to try and solve people's problems when I get the chance. Realised I was truly a programmer the day I watched my coursemate type the word 'python' in a suggestive text to a female and it autocorrected to an uppercase 'P'. No going back once you're in with a circle like that.
Updated on June 27, 2022Comments
-
marcuthh almost 2 years
I have a thread that runs in the background of my program and detects when a deadline (set by user input at the beginning of the program) occurs. I have implemented this in a
while
loop and using thesleep(1000)
method.It all works ok, but I would like to change it over from using
sleep(1000)
to usingwait()
andnotifyAll()
to be consistent with the rest of my code, and to make the alert happen in real-time rather than lagging by a part of a second until the thread re-awakens.Here is what I currently have
//Retrieve current date and time... Calendar now = Calendar.getInstance(); //deadline not yet reached while(now.before(deadline)) { try { //wait a second and try again sleep(1000); } catch (InterruptedException intEx) { //Do nothing. } //Update current date and time... now = Calendar.getInstance(); //run loop again } //////////////////////////// ///alert user of deadline/// ////////////////////////////
I have tried to change it over to use
wait()
, but had no success. Can anybody see a way of changing the existing code over to implement the methods I mentioned?Thanks in advance, Mark
-
marcuthh about 8 yearsHi there, how does this method work? Will it just wait until the deadline is reached, and then drop out of the while loop?
-
Vishy about 8 years@marcuthh it does say what it does in the javadoc. Note this is for working with a lock. If you are not locking an object it doesn't make sense to
wait
on it.