In Thread.sleep()
JavaDoc, it stated that:
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.
My question is: if thread A holds a monitor and goes to sleep, then the thread scheduler would choose another runnable thread B and run it. But if thread B need that monitor, then it will be blocked, and any other thread depending on the monitor will be blocked until thread A resume from sleep and get to run and release that monitor, is it very inefficient
CodePudding user response:
Yes.
What other answer were you expecting?
If you're holding a monitor, don't sleep, obviously. Instead use wait and notify.
Here's what happens when you use wait, which you call on an object that you have to hold the monitor on if you want to use it:
synchronized (foo) {
do stuff()
foo.wait();
do more stuff();
}
When wait() is invoked, first, the thread releases the monitor. Next it'll just twiddle its thumbs and waits for somebody, anybody, to invoke notify()
on the same reference (foo.notify()
). At that point, the wait()
method is released, but will still wait around as it now needs to re-acquire that monitor before continuing. This neccessarily cannot happen immediately, as notify()
cannot be called unless you hold the monitor.
That nicely solves your problem: You can have a thread sleeping whilst releasing that one monitor (it does not release other monitors, though).
More generally though, using these low level APIs is almost never the right move. There are abstractions, mostly in the java.util.concurrent
package, that are much nicer. You should open the javadoc and have a good read through.