I am creating a multiple threads and calling yield() inside it.
The java.lang.Thread.yield() method causes the currently executing thread object to temporarily pause and allow other threads to execute.
Will It be possible for other threads to execute which also want to go inside synchronized block?
synchronized(this.lock)
{
//calling yield here.
}
thanks.
As far as I know, Yield() only gives up the remaining time slice on the CPU and steps back in the queue. It doesn't release any synchronized objects.
yield does not take or release locks, it simply pauses the current thread execution. So yielding in the synchronized block will not let the current thread to release lock and let the other methods to enter the synchronized block. wait/notify method should be used to release the lock.
From Java Language Specification
Thread.sleep causes the currently executing thread to sleep
(temporarily cease execution) for the specified duration, subject to
the precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors, and resumption of execution
will depend on scheduling and the availability of processors on which
to execute the thread.
It is important to note that neither Thread.sleep nor Thread.yield have any synchronization semantics. In particular, the compiler does
not have to flush writes cached in registers out to shared memory
before a call to Thread.sleep or Thread.yield, nor does the compiler
have to reload values cached in registers after a call to Thread.sleep
or Thread.yield.
yield allows a context switch to other threads, so this thread will not consume the entire CPU usage of the process. The thread still holds the lock. It is the developer responsibility to take care of deadlocks.
Related
Let's say you have two threads, thread1 and thread2. If you call thread1.start() and thread2.start() at the same time and they both print out numbers between 1 and 5, they will both run at the same time and they will randomly print out the numbers in any order, if I am not mistaken. To prevent this, you use the .join() method to make sure that a certain thread gets executed first. If this is what the .join() method does, what is the Lock object used for?
Thread.join is used to wait for another thread to finish. The join method uses the implicit lock on the Thread object and calls wait on it. When the thread being waited for finishes it notifies the waiting thread so it can stop waiting.
Java has different ways to use locks to protect access to data. There is implicit locking that uses a lock built into every Java object (this is where the synchronized keyword comes in), and then there are explicit Lock objects. Both of them protect data from concurrent access, the difference is the explicit Locks are more flexible and powerful, while implicit locking is designed to be easier to use.
With implicit locks, for instance, I can't not release the lock at the end of a synchronized method or block, the JVM makes sure that the lock gets released as the thread leaves. But programming with implicit locks can be limiting. For instance, there aren't separate condition objects so if there are different threads accessing a shared object for different things, notifying only a subset of them is not possible.
With explicit Locks you get separate condition objects and can notify only those threads waiting on a particular condition (producers might wait on one condition while consumers wait on another, see the ArrayBlockingQueue class for an example), and you can implement more involved kinds of patterns, like hand-over-hand locking. But you need to be much more careful, because the extra features introduce complications, and releasing the lock is up to you.
Locking typically prevents more than one thread from running a block of code at the same time. This is because only ONE thread at a time can acquire the lock and run the code within. If a thread wants the lock but it is already taken, then that thread goes into a wait state until the lock is released. If you have many threads waiting for the lock to be released, which one gets the lock next is INDETERMINATE (can't be predicted). This can lead to "thread starvation" where a thread is waiting for the lock, but it just never gets it because other threads always seem to get it instead. This is a very generic answer because you didn't specify a language. Some languages may differ slightly in that they might have a determinate method of deciding who gets the lock next.
I'm learning about multiple threading in Java. Following is demo code, and I'm curious about the usage of Thread.yield() inside of the function.
Isn't it a synchronized function, which cannot be called until the running task finishes its work on it? Then what is the difference between inserting Thread.yield() into this block and not?
Demo code:
public class SynchronizeEvenGenerator {
private int currentEvenValue = 0;
/**
* Generate even and return it
* #return
*/
public synchronized int next() {
++currentEvenValue;
Thread.yield();
++currentEvenValue;
return currentEvenValue;
}
}
What will happen if Thread.yield() is called in a synchronized function?
As the javadoc for Thread.yield() states:
"[This is 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."
So there are two possibilities:
Nothing happens; i.e. the yield() call returns immediately.
Another thread is scheduled and gets to execute. Eventually, this thread is rescheduled and the yield() call returns.
One thing does not happen. The thread does not relinquish the mutex. Any other thread that happened to be blocked waiting to acquire the mutex will remain blocked.
Isn't it a synchronized method, which cannot be called until the running task finishes its work on it?
Thread.yield is not a synchronized method. (And even if it was, it would be locking the Thread object, not the lock that the synchronized block is currently holding.)
So, in your example, a call to next() is guaranteed to increment the counter by exactly 2. If some other thread calls the next() method, the second call will remain blocked until (at least) after the first call returns.
The javadoc also says this:
"It is rarely appropriate to use this method."
Another question: Will it become an deadlock for thread scheduling
No. The thread that called yield() will eventually be rescheduled.
(Deadlock is a very specific phenomenon (see Wikipedia article) that can only occur when a lock is acquired. When a thread yields, it neither acquires or releases locks, so it cannot cause a deadlock.)
Now, when a thread yields, it might be a long time before it gets scheduled again, especially if there are lots of other runnable threads at the same or higher priority. The net result is that other threads waiting to acquire the lock could held up for a long time. This can unduly increase contention and congestion. But eventually, the yield() call will return, the next() call will return and another thread will be able to acquire the lock.
In short: calling yield() while holding a lock is bad for performance, but it won't directly cause a deadlock.
As the javadoc says, calling yield() is rarely appropriate.
Isn't it an synchronized function which cannot be called until the running task finish it's work on it ?
It can't be running in another thread for the same object.
Then what is the diff between insert Thread.yield() into this block and not ?
The CPU which is running the thread could be context switched to another available thread for any process on the system.
If there is no waiting thread to run, it will make it slower by about 15 - 30 micro-seconds.
c.f. wait(0) which can allow another thread to obtain the lock.
A potentially blocking action (e.g. Thread.join(), obj.wait(), monitorEnter ), may continue to execute under some circumstances (e.g. For Thread.join(), if the interrupt flag is set by the time of calling, the method won't block. For obj.wait(), if the interrupt flag is set and monitor is available, the action won't block). Under these circumstances, will the java thread continue in the current CPU timeslice; or will it release the current timeslice and wait for next dispatch?
Your question is a little confused - a thread can only call wait if it already owns the monitor. Which is acquired by entering a synchronised block and going through the monitorEnter process.
But to try and answer your question: if a thread invokes a potentially blocking action (i.e, needs to acquire the object monitor), will it always lose the timeslice? The answer is no. It will try a couple of "fast path" attempts first, and only then will it park the thread.
The code for monitor synchronisation is here: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/runtime/synchronizer.cpp#l1192
The VM first tries a very quick atomic CAS operation to get the monitor. If that fails it tries a short spinlock (to hold the CPU). If the spinlock fails then it parks the thread.
The park happens here under Windows: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/os/windows/vm/os_windows.cpp#l4787
where it looks like it calls the Windows WaitForSingleObject API function.
There is no guarantee it will lose the CPU, nor that it will be blocked for a whole time slice if;
the operation can be performed immediately.
the operation might busy wait for a short time before giving up the CPU, but it might complete in that time.
the thread might get the CPU back within the time slice.
How this exactly work depends mostly on the OS. The busy waiting strategy is sometimes implemented in Java, in which case you will see it in the source code.
if anotherThread.join() is executed, and anotherThread has finished, there will be no loss of CPU timeslice. Similary, if monitorEnter obj is executed, and obj is not locked, execution will continue without interruption.
If you deliberately want to release the current timeslice and wait for next dispatch, then call to Thread.yield() or Thread.sleep(0), but JVM implementation may ignore your hint.
I understand that Thread.currentThread().yield() is a notification to thread scheduler that it may assign cpu cycle to some other thread of same priority if any such is present.
My question is: If current thread has got lock on some object and calls yield(), will it loses that lock right away? And when thread scheduler finds out there is no such thread to assign cpu cycle, then the thread which has called yield() will again be in fight to get lock on the object which it has lost earlier??
I couldn't find it in javadoc and forums [http://www.coderanch.com/t/226223/java-programmer-SCJP/certification/does-sleep-yield-release-lock] have 50-50 answers.
I think yield() (lets say thread1) should release lock because if some thread (lets say thread2) of same priority wants to operate on same object, then it can have chance when thread scheduler eventually assign cup to thread2.
No. Thread.yield() is not like Object.wait(). It just gives up control to allow a thread switch. It will have no effect on the concurrency of your program.
There is no guarantee which thread the scheduler will run after a yield.
In Java Language specification
17.3 Sleep and Yield
It is important to note that neither Thread.sleep nor Thread.yield have any synchronization semantics. In particular, the compiler does not have to flush writes cached in registers out to shared memory before a call to Thread.sleep or Thread.yield, nor does the compiler have to reload values cached in registers after a call to Thread.sleep or Thread.yield.
My comment:
In java's early days, when it did not really supported parallel executions, but only concurrent (green threads), yield() was suspending the current thread, and the jvm was picking up another thread to resume. Now-days, yield does not have much meaning as usually the tread scheduling is on OS level.
So, yield is just a hint to the JVM that current thread wants to take a rest and nothing else, it is up to the thread scheduler to decide what to do. yield does not have any synchronization semantic. If thread holds lock, it will continue to hold it.
Only wait methods of the Object class release the intrinsic lock of the current instance (the thread may have other locks acquired, they don't get released). Yield, sleep, join do not bother about locks. However, join is a little more special, you are guaranteed to see all the changes made by the thread you're waiting for to finish.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Does thread.yield() lose the lock on object if called inside a synchronized method?
I know Thread.sleep() holds the lock, but Object.wait() releases the lock. Some say yield actually implements sleep(0). Does this mean yield will not release the lock?
Another question. Say the current thread has acquired a lock, and then called anotherThread.join(). Does the current thread release the lock?
Unless the javadoc mentions an object's monitor (such as Object.wait()), you should assume that any locks will continue to be held. So:
Does this mean yield will not release the lock?
Yes.
Does the current thread release the lock?
No.
sleep puts the thread in a wait state, yield returns the thread directly to the ready pool. (So if a thread yields it could go directly from running to the ready pool to getting picked by the scheduler again without ever waiting.) Neither one has anything to do with locking.
From the Java Language Specification:
Thread.sleep causes the currently executing thread to sleep
(temporarily cease execution) for the specified duration, subject to
the precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors, and resumption of execution
will depend on scheduling and the availability of processors on which
to execute the thread.
It is important to note that neither Thread.sleep nor Thread.yield
have any synchronization semantics. In particular, the compiler does
not have to flush writes cached in registers out to shared memory
before a call to Thread.sleep or Thread.yield, nor does the compiler
have to reload values cached in registers after a call to Thread.sleep
or Thread.yield.
For example, in the following (broken) code fragment, assume that
this.done is a non-volatile boolean field:
while (!this.done)
Thread.sleep(1000);
The compiler is free to read the field this.done just once, and reuse
the cached value in each execution of the loop. This would mean that
the loop would never terminate, even if another thread changed the
value of this.done.