monitors & notify & notify all in Java - java

I'm doing an online quiz related to monitors. Those are the 4 true or false questions and my answers. If my answers are wrong, can you please explain why?
Starvation will definitely not occur when using monitors in Java if notifyAll() is used T
Only objects that are declared to extend thread or implement runnable have a monitor lock in Java F

Starvation will definitely not occur when using monitors in Java if notifyAll() is used. F
If a thread is not granted CPU time because other threads grab it all, it is called "starvation". Check here for
more.
When using notifyAll(), JVM awakens all threads and then all
threads race for the lock on this object. Now, CPU scheduler selects
a thread which acquires lock on this object. This means using
notifyAll() can not avoid starvation since some threads may always lose the contention.
Also, Threads are blocked indefinately waiting to enter a
synchronized block, because other threads are constantly allowed
access before it. Starvation will also occur.
Only objects that are declared to extend thread or implement runnable
have a monitor lock in Java. F
Every class roots from java.lang.Object has monitor lock. Check here for more.

Related

Difference between Locks and .join() method

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.

How to find which threads currently hold java.util.concurrent.Semaphore permits?

I am trying to analyze a thread dump which seems to indicate that there are numerous threads that are waiting on java.util.concurrent.Semaphore permits, i.e., the threads are waiting on Semaphore.acquire().
This I was able to imply because the threads are in WAITING (parking) state, and from what I've understood, Semaphore's do not use LOCK monitors, but use LockSupport.park() instead, waiting on another thread to unpark it.
Now, is there a way to imply from a thread dump on what all threads currently hold the Semaphore permits?
Similar to finding threads in BLOCKED state, and check which is the thread that holds the LOCK which is causing the thread to BLOCK?
Semaphores do not have a concept of ownership or know anything about threads. This makes them particularly lightweight (and useful in asynchronous programming where your logical thread of execution and the hardware thread on which it is executed won't necessarily have a 1:1 mapping).
You can also see this from the fact that a thread can release a semaphore without ever having acquired it.
You will have to look at the stacktraces to see where on what semaphores the threads are waiting and work backwards from there.
There are tools that help you to analyse dumps.Yourkit is one such tool that can be used to analyse blocked threads.
Reference:
https://www.yourkit.com/docs/java/help/monitor_profiling.jsp

Synchronized on a monitor

I'm just trying to further my understanding of this concept.
We have a monitor, let's say a queue or a map of some sort. This monitor has methods to put objects on, and get objects off. In order to be thread safe, the monitor will lock on it's put methods and on it's get methods. When a thread is synchronized to this monitor, it's constantly trying to obtain this monitor's right's so it can proceed with what it needs to do. Does this sound right?
Another question, how does the flow of control work here. Which code is executed once the thread has gained access to the monitor? I'm finding it hard to debug multi-threaded programs with just print statements, it get's really messy and confusing.
public void run(){
try{
synchronized (monitor){
while (monitor is empty){
monitor.wait(); // Does this line pause the thread or the monitor?
}
System.out.println("Done Waiting");
}
System.out.println("Out of the synchronized block");
}
}
Here's the definition from the Java Language Specification:
The Java programming language provides multiple mechanisms for
communicating between threads. The most basic of these methods is
synchronization, which is implemented using monitors. Each object in
Java is associated with a monitor, which a thread can lock or unlock.
Only one thread at a time may hold a lock on a monitor. Any other
threads attempting to lock that monitor are blocked until they can
obtain a lock on that monitor. A thread t may lock a particular
monitor multiple times; each unlock reverses the effect of one lock
operation.
To answer
This monitor has methods to put objects on, and get objects off. In
order to be thread safe, the monitor will lock on it's put methods and
on it's get methods. When a thread is synchronized to this monitor,
it's constantly trying to obtain this monitor's right's so it can
proceed with what it needs to do. Does this sound right?
So you're not interacting with a monitor. A monitor doesn't have a concept of methods. Don't think of it like that. You interact with objects which have monitors. When a thread acquires an object's monitor, it doesn't need to constantly trying to obtain it, it already has it.
Another question, how does the flow of control work here. Which code
is executed once the thread has gained access to the monitor? I'm
finding it hard to debug multi-threaded programs with just print
statements, it get's really messy and confusing.
If execution enters the synchronized block on an object, the currently executing thread has acquired the monitor on the synchronized object, in this case the object referenced by the variable monitor.
I'll assume (thanks to Radiodeaf) that by monitor is empty, you mean your Map object doesn't have any entries.
When you call
monitor.wait();
the current thread releases the monitor on the object referenced by monitor and sleeps until it gets notified.
The javadoc of Object#wait() has more details.
So you will loop on the check for empty and wait if it returns true. We can assume that some other piece of code calls notify() when they put something into the Map.
When the object does get notified, the thread then has to compete to re-acquire the object's monitor. This is obviously necessary so that the thread can be executing inside a synchronized block on the object.
As we know We can call wait method only from synchronized context.
So By saying wait release the lock we mean that once lock is acquired on an object when it is in synchronized context , by calling wait method on same object , it release the lock and allow other thread to work on that object.

Are Java wait(), notify() 's implementation significantly different from locks?

Out of curiosity, when Java implements wait() and notify() methods, are they really just using locks? i.e., wait() acquires a mutex, notify() release a mutex, notifyAll() releases all mutexes (in the same object, of course)?
Other than being less cumbersome than using locks, are there other advantages of using wait() and notify()?
[EDIT] I realized what I confused myself about after Brian's comments:
wait doesn't lock, it releases the lock and passes it to someone else who's waiting on a synchronized statement for the mutex, then waits to be notified by someone else who has the lock and calls notify, which passes the lock back to the original thread that called wait. I think that's where you're getting confused. – Brian 17 mins ago
The other questions have focused on what the language says that wait and notify are - but that doesn't seem to be what your question is about... you talk about mutexes, which is an implementation detail and therefore JVM specific.
So we need to pick a JVM - let's pick openjdk (source available here). The bit of code that (ultimately) handles all this stuff is found at hotspot/src/share/vm/runtime/objectMonitor.cpp.
This maintains two datastructures - a wait set and an entry set. Waiting threads are added to the wait set and parked whereas threads attempting to take the monitor are added to the entry set and then parked. On notify a thread is taken from the wait set and added to the entry set. When a thread releases the lock it unparks a thread from the entry set if there is one. Note that these sets are actually implemented as queues (linked lists) so are treated on a FIFO basis.
Therefore, in this particular case the implementation treats waiting on an object's monitor and attempting to take an object's monitor in a similar way.
But this is just one implementation of one JVM (although it's likely that others do something similar) - so we cannot rely on it. So I suppose the question is why do you want to know? If it's just curiosity then look through the openjdk code, it's fascinating. If you plan on using this information in your code... don't.
UPDATE
I realise that saying "park" doesn't tell us much. The code that parks a thread is platform specific (and is implemented in an object called PlatformEvent, which ParkEvent extends). In the version of openjdk that I'm looking at the park code for linux can be found at hotspot/src/os/linux/vm/os_linux.cpp and this calls pthread_mutex_lock(_mutex)... so in answer to your question yes calling wait may take a mutex on my machine. Note that there's lots of stuff that happens above this which might prevent us getting to this point.
wait() and notify() don't do any monitor acquisition. as the javadoc for these methods state, the caller must have acquired the monitor before calling. in fact, wait() actually releases the monitor the caller acquired (although, i guess technically wait does do monitor (re)acquisition before finally returning).
wait releases the lock you already have with the intention of re-obtaining it at some point in the future after someone else calls notify. This is in addition to the locking mechanisms provided by synchronized. Basically, you use synchronized to obtain a lock, then you use wait, notify, and notifyAll to control how those locks are released and re-locked.
Out of curiosity, when Java implements wait() and notify() methods, are they really just using locks?
i.e., wait() acquires a mutex, notify() release a mutex, notifyAll() releases all mutexes?
Sorry, but none of that quite right. :)
It is the synchronized keyword that obtains the monitor. i.e. this is a form of locking. NB: using java.util.concurrent.locks.Lock does something similar.
wait() 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. Nothing to do with locking - but can only call this method when the current thread current thread already own's this object's monitor (in a synchronized block/method)
notify() wakes up a single thread that is waiting on this object's monitor. Again, nothing to do with locking - but can only call this method when the current thread current thread already own's this object's monitor (in a synchronized block/method)
wait(), notify() always work along with Synchronization , so comparison can be between Locks and synchronization. There is big difference between Locks like RentrantLock, ReadWriteLock and Synchronization [block, methods].
Locks dont use synchronization internally while wait(), notify() will need synchronization.
You use Lock along with java.util.concurrent.locks.Condition, which efficiently enables conditional locking, this is quite tedious to implement with synchronization..
You dont have any tryLock option with synchronization , you either take lock or wait. But with Lock interface you have the choice.

Does thread.yield() lose the lock on object if called inside a synchronized method?

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.

Categories