9

So far what I have understood about wait() and yield () methods is that yield() is called when the thread is not carrying out any task and lets the CPU execute some other thread. wait() is used when some thread is put on hold and usually used in the concept of synchronization. However, I fail to understand the difference in their functionality and i'm not sure if what I have understood is right or wrong. Can someone please explain the difference between them(apart from the package they are present in).

Olimpiu POP
  • 5,001
  • 4
  • 34
  • 49
Awani
  • 394
  • 3
  • 7
  • 19
  • 2
    Well, if you `.wait()`, another thread has to `.notify()` you -- on the exact same object reference. `.yield()` is simply a hint to the JVM that "if you ant to schedule me out, you can for the moment" – fge Nov 07 '14 at 09:34
  • So aren't they both doing the same task - waiting so that other threads can execute? Also, when using yield(), how will the thread come back to runnable state? – Awani Nov 07 '14 at 09:41

4 Answers4

30

aren't they both doing the same task - waiting so that other threads can execute?

Not even close, because yield() does not wait for anything.

Every thread can be in one of a number of different states: Running means that the thread is actually running on a CPU, Runnable means that nothing is preventing the thread from running except, maybe the availability of a CPU for it to run on. All of the other states can be lumped into a category called blocked. A blocked thread is a thread that is waiting for something to happen before it can become runnable.

The operating system preempts running threads on a regular basis: Every so often (between 10 times per second and 100 times per second on most operating systems) the OS tags each running thread and says, "your turn is up, go to the back of the run queue' (i.e., change state from running to runnable). Then it lets whatever thread is at the head of the run queue use that CPU (i.e., become running again).

When your program calls Thread.yield(), it's saying to the operating system, "I still have work to do, but it might not be as important as the work that some other thread is doing. Please send me to the back of the run queue right now." If there is an available CPU for the thread to run on though, then it effectively will just keep running (i.e., the yield() call will immediately return).

When your program calls foobar.wait() on the other hand, it's saying to the operating system, "Block me until some other thread calls foobar.notify().

Yielding was first implemented on non-preemptive operating systems and, in non-preemptive threading libraries. On a computer with only one CPU, the only way that more than one thread ever got to run was when the threads explicitly yielded to one another.

Yielding also was useful for busy waiting. That's where a thread waits for something to happen by sitting in a tight loop, testing the same condition over and over again. If the condition depended on some other thread to do some work, the waiting thread would yield() each time around the loop in order to let the other thread do its work.

Now that we have preemption and multiprocessor systems and libraries that provide us with higher-level synchronization objects, there is basically no reason why an application programs would need to call yield() anymore.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
  • 100 times a second might seem like a lot, but if you have two threads that are highly depended on each other, yielding can potentially save you the 1/100 of a second over each cycle. For example, let's say that you are trying to mark all the even numbers in an array while the other threads do the same for the odd numbers, and you can't allow them to have a gap bigger than a 100. With such extreme dependency, wait() may cause a significant performance decrease, while yielding not so much. – Ilya Gazman Sep 28 '18 at 14:47
  • @IlyaGazman, The javadoc for `Thread.yield()` makes it quite clear that it is not required to do anything at all. You can't rely on it for any purpose whatsoever because it might literally do _nothing_ when you call it. – Solomon Slow Sep 28 '18 at 22:08
8

wait is for waiting on a condition. This might not jump into the eye when looking at the method as it is entirely up to you to define what kind of condition it is. But the API tries to force you to use it correctly by requiring that you own the monitor of the object on which you are waiting, which is necessary for a correct condition check in a multi-threaded environment.

So a correct use of wait looks like:

synchronized(object) {
  while( ! /* your defined condition */)
    object.wait();
  /* execute other critical actions if needed */
}

And it must be paired with another thread executing code like:

synchronized(object) {
  /* make your defined condition true */)
  object.notify();
}

In contrast Thread.yield() is just a hint that your thread might release the CPU at this point of time. It’s not specified whether it actually does anything and, regardless of whether the CPU has been released or not, it has no impact on the semantics in respect to the memory model. In other words, it does not create any relationship to other threads which would be required for accessing shared variables correctly.

For example the following loop accessing sharedVariable (which is not declared volatile) might run forever without ever noticing updates made by other threads:

while(sharedVariable != expectedValue) Thread.yield();

While Thread.yield might help other threads to run (they will run anyway on most systems), it does not enforce re-reading the value of sharedVariable from the shared memory. Thus, without other constructs enforcing memory visibility, e.g. decaring sharedVariable as volatile, this loop is broken.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • More often than not, it's better to use `notifyAll()` instead of `notify`, since different threads can wait for different conditions to occur, and if you use `notify` it may go to wrong thread, and this notification is lost for thread it really belongs to. If you know that there's no more than one waiting thread, using `notify` is fine. – Victor Sorokin Nov 07 '14 at 10:27
  • @Victor Sorokin: it obviously depends on the condition. E.g. if you put exactly one item into an empty queue there is no reason to wake up more than one consumer. If you have multiple different conditions you may consider using a [`Lock`](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html) as that API supports defining distinct [conditions](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html) you may `await` and `signal`. – Holger Nov 07 '14 at 10:32
  • Well, you right there's explicit `Condition` for this, but one can't say it's safe to use `notify` in case of multiple consumers, _in a general case_ (e.g., what if different consumers consume differnt type of items?). – Victor Sorokin Nov 07 '14 at 10:36
  • @Victor Sorokin: in that case you *have* different conditions, as you are not waiting for “nonempty condition” but “Foo available” and “Bar available” then. In that case you need either the consumer doing a re-`notify` if it didn’t consume or the producer using `notifyAll` whereas the former may soon become even more inefficient as the latter. So right, if in doubt, just use `notifyAll`… – Holger Nov 07 '14 at 10:42
  • @VictorSorokin, while `notifyAll` seems the go-to solution it has a pretty terribly performance impact when more than a single thread is involved. All threads have to acquire the monitor effectively causing a lot of coherency traffic and CPU wastage. That being said if there are different conditions for the same lock, you probably want to refactor the code and use more locks. – bestsss Nov 07 '14 at 17:40
3

The first difference is that yield() is a Thread method , wait() is at the origins Object method inheritid in thread as for all classes , that in the shape, in the background (using java doc)

wait()

Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).

yield()

A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.

and here you can see the difference between yield() and wait()

Abdullah Khan
  • 12,010
  • 6
  • 65
  • 78
indian
  • 130
  • 8
0

Yield(): When a running thread is stopped to give its space to another thread with a high priority, this is called Yield.Here the running thread changes to runnable thread.

Wait(): A thread is waiting to get resources from a thread to continue its execution.

pt7092
  • 11
  • 2