5

Here's a snippet of code that I saw in some code I'm maintaining.

Object lock = new Object();

synchronized( lock ) 
{
   try
   {
       lock.wait( 50000 );
       Thread.sleep( 3000 );
   } 
   catch(Exception ex)
   {
   }
}

The developer wants to suspend the current thread for some amount of time and is using Object#wait as the mechanism. Obviously it is bad form to use the wait/notify protocol for this reason; however, is there any major difference between calling wait(millisec) and a Thread.sleep ?

Jacques René Mesrine
  • 46,127
  • 27
  • 66
  • 104

3 Answers3

4

Aside from having to get a monitor before waiting() there's no major difference anymore so long as no one external is going to be .notify()ing.

In ancient Java code you'd see people using wait() instead of Thread.sleep() because Thread.sleep() would freeze the whole application on systems without preemptive multitasking (I'm looking at you OS9). Technically wait() also let's you use nano-resolution waits, but in practice they're seldom that accurate.

Ry4an Brase
  • 78,112
  • 7
  • 148
  • 169
  • Ok so I want to *pause* a thread for x seconds. How do I decide if I should use wait() or sleep() ? – Pacerier Feb 03 '12 at 09:17
  • I explained that in my answer: the biggest difference is if some other thread is going to be allowed to wake you up. With 'wait' you have the 'lock' object to wait on and they can notify it to end you sleep early. With sleep() they'd need a reference to the sleeping thread itself to interrupt you. – Ry4an Brase Feb 04 '12 at 17:45
  • @Ry4an No I mean, I want to *pause* a thread for x seconds without anyone going to wake me up. So I can *Object.wait(timeout)* and I can *Thread.sleep(timeout)*. How do I decide which to use? – Pacerier Mar 08 '12 at 08:41
  • 1
    Third time: **either works**. If you don't need another thread to interrupt the sleep/wait then they're effectively identical. – Ry4an Brase Mar 08 '12 at 14:49
4

Note that there is one key difference in using Object.wait() and Thread.sleep() inside a synchronization block: Thread.sleep() does not release the locked monitor, so no-one else can become the owner of the monitor.

In addition, Object.wait() does not guarantee that the delay indicated will be obeyed strictly. First of all, after the delay passes, the thread may still be waiting for another thread that has become the monitor owner in the meantime; and it may compete with other threads waiting to grab the monitor.

Second, the mythical spurious wake-up, as it is described in the Java 6 API javadoc:

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup.

Unlikely as it is, every piece of code using Object.wait() should take it into consideration.

Bartosz Klimek
  • 555
  • 2
  • 5
3

You say it's "obviously" bad form to use wait/notify for this, but I don't see anything wrong with it. Admittedly following it up with a sleep call is very odd (and swallowing exceptions is bad), but I've definitely used Object.wait as a "breakable sleep" before now.

Imagine you've got a thread polling a resource every minute, but you want to be woken if something's happened (e.g. the resource location has changed, or the timer frequency has changed, or the program wants to quit in a graceful manner). Using wait/notify works extremely well for that - it's definitely cleaner than calling interrupt on the thread from elsewhere, as it doesn't matter if the notify occurs while you're actually processing instead of waiting.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • IMHO, it is bad form in this case because the wait is happening outside of a while loop. – Jacques René Mesrine Apr 02 '09 at 05:49
  • @Jacques: It would have been helpful if you'd stated that in the question. All you presented was a snippet - so what you presented *wasn't* "obviously bad form". Even without a while loop it could be reasonable as a "timer with easy cancellation" basically. – Jon Skeet Apr 02 '09 at 06:35
  • My apologies. Basically all the code you see is inside a method of a class. lock is a member variable of the class. – Jacques René Mesrine Apr 02 '09 at 10:13