From Programming Language Pragmatics, by Scott
Java objects that use only synchronized methods (no locks or
synchronized statements) closely resemble Mesa monitors in which
there is a limit of one condition variable per monitor (and in fact
objects with synchronized statements are sometimes referred to as
monitors in Java).
Why are Java objects that use only synchronized methods closely resemble Mesa monitors in which there is a limit of one condition variable per monitor?
Is it correct that there is no condition variable in "Java objects that use only synchronized methods"? So how can it resembles a monitor with one condition variable?
By the same token, a synchronized statement in Java that begins
with a wait in a loop resembles a CCR in which the retesting of
conditions has been made explicit. Because notify also is explicit,
a Java implementation need not reevaluate conditions (or wake up
threads that do so explicitly) on every exit from a critical
section—only those in which a notify occurs.
Why does a synchronized statement in Java that begins
with a wait in a loop resembles a CCR (conditional critical region) in which the retesting of conditions has been made explicit?
What does it mean by "Because notify also is explicit, a Java implementation need not reevaluate conditions (or wake up threads that do so explicitly) on every exit from a critical section—only those in which a notify occurs"?
Thanks.
All this is saying is that in Java intrinsic locks have the condition baked into them. Contrast this with ReentrantLock where you can explicitly have separate conditions with the same lock.
If you have separate conditions then you can signal a given condition and know only threads in the wait set for that condition will receive it. If you don't have separate condition objects then upon being notified you have to check to see if that condition applies to you.
An example of this would be a fixed size blocking queue. If you look at ArrayBlockingQueue, it's implemented with ReentrantLock so that putting and taking use separate condition objects. If this was implemented using the intrinsic lock on the Queue object it would have to use notifyAll to wake up waiting threads, which would then have to test the condition they woke up from waiting on to find out if it was relevant to them.
Here is a blocking queue written using an intrinsic lock. If notify was used then a single thread would be woken by the scheduler and (since threads could be waiting to put or waiting to take) it might or might not be one that the notify was relevant to. To make sure the notification doesn't get lost all the waiting threads get notified:
public class Queue<T>{
private final int maxSize;
private List<T> list = new ArrayList<>();
public Queue(int maxSize) {
this.maxSize = maxSize;
}
public synchronized T take() throws InterruptedException {
while (list.size() == 0) {
wait();
}
notifyAll();
return list.remove(0)(
}
public synchronized void put(T entry) throws InterruptedException {
while (list.size() == maxSize) {
wait();
}
list.add(entry);
notifyAll();
}
}
As shown in example below, once lock is taken on an object in call method, there is no need for further methods to have synchronized keyword.
public class Prac
{
public static void main(String[] args)
{
new Prac().call();
}
private synchronized void call()
{
further();
}
private synchronized void further()
{
oneMore();
}
private synchronized void oneMore()
{
// do something
}
}
But, if I still add synchronized keyword to further and onceMore, what java does on such encounters? Does java checks if lock is required or not? or as method call is in same stack, it just proceeds without checking if lock is required or not as lock is already acquired.
Note : My doubt is how java will behave in such situation, I am not sure, but I think it is different from biased locking.
In fact, java checks if the current thread has the lock every time it enters a synchronized method.
private synchronized void oneMore()
{
// do something
}
This is equivalent to
private void oneMore(){
synchronized(this){
// do something
}
}
But because of the fact that intrinsic locks in java are reentrant; if a thread has the lock, it doesn't reacquire it once it enters another synchronized block as in you example. Otherwise, this will create a deadlock.
Update: To answer your comment below. From Java Concurency in practice:
Reentrancy is implemented by associating with each lock an acquisition count
and an owning thread. When the count is zero, the lock is considered unheld.
When a thread acquires a previously unheld lock, the JVM records the owner
and sets the acquisition count to one. If that same thread acquires the lock
again, the count is incremented, and when the owning thread exits the
synchronized block, the count is decremented. When the count reaches zero,
the lock is released.
Therefore, checking if a lock is acquired, is equivalent to an if statement (more or less) that the variable holding the owning thread is equal or not to the thread trying to acquire the lock.
However, as you pointed out, there is no need for the synchronized keyword on the private methods. In general, you should try to remove unnecessary synchronization since that usually leads to degraded performance.
Question 1:
I was reading into Hard-core Multi-threading in Java and did bump up into the semaphore example below.
package com.dswgroup.conferences.borcon.threading;
public class ResourceGovernor {
private int count;
private int max;
public ResourceGovernor(int max) {
count = 0;
this.max = max;
}
public synchronized void getResource(int numberof) {
while (true) {
if ((count + numberof) <= max) {
count += numberof;
break;
}
try {
wait();
} catch (Exception ignored) {}
}
}
public synchronized void freeResource(int numberof) {
count -= numberof;
notifyAll();
}
}
I feel this can lead to deadlock in the below scenario :
All resources are being used and a new thread asks for resources that are not available.
Since it waits inside the synchronized function, the other threads that are using the resources are not able to free the resources as the freeResource function is also synchronized and that they can't enter the function as the waiting thread has taken the object level lock of ResourceGovernor
There is another issue that one has not validated if a thread is trying to release more no. of resources than it acquired. But this issue is secondary and can be easily fixed by having the synchronized map of thread name and resource count.
But can i safely say that i diagnosed the 1st problem correctly. (Need to doublecheck since its published for a long time on embarcadero.com)
Question 2:
Can i safely say that a semaphore with only 1 resource has the same behaviour as a mutex lock?
All resources are being used and a new thread asks for resources that are not available. Since it waits inside the synchronized function, the other threads that are using the resources are not able to free the resources as the freeResource function is also synchronized and that they can't enter the function as the waiting thread has taken the object level lock of ResourceGovernor
You've missed the fact that calling wait() relinquishes the monitor, so other synchronized code is able to execute. From the docs for wait():
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
For your second question:
Can I safely say that a semaphore with only 1 resource has the same behaviour as a mutex lock?
I suspect so, although the implementation you've shown doesn't actually stop you from calling freeResource several times. It's a slightly odd implementation in that I normally see semaphores counting the number of resources remaining rather than the number of resources taken - although they're equivalent, of course.
Question 2 : Yes it is similar to mutex. But although mutexes and semaphores have similarities in their implementation, they should always be used differently. Nice Explanation Here
I have been playing around with implementing my own very basic semaphore and have noticed that the implementation I choose influences whether or not I get a deadlock. But I don't understand how the deadlock is happening.
My original implementation (no deadlock):
public synchronized void waitFor(){
value--;
if(value < 0)
wait();
}
public synchronized void signal(){
value++;
notify();
}
A later implementation (results in deadlock):
public synchronized void waitFor(){
value--;
while(value < 0)
wait();
}
public synchronized void signal(){
value++;
notifyAll();
}
The wait() is actually surrounded by a try-catch in both sets of code for catching thread interruptions, but I have left it out for readability and am assuming it makes no difference to the deadlock issue.
Anyone have any ideas?
I can't spot any deadlock risk with the second implementation. The while loop is the right choice for waiting on a lock (See spurious wakeups in Object.wait() documentation).
Also, it looks like no signal operation can be missed. A signal can only occur when another thread is in a wait state, or when no other thread is running waitFor().
Therefore, I suggest that you check other parts of the code:
Do all threads synchronize on the same instance of the semaphore?
Are you sure that the value counter isn't used elsewhere, in a
non-thread-safe manner?
Do all threads call sepmaphore.signal() when
they are done? (Typically this kind of release operations are placed in a finally block).
This is because a synchronized method actually locks the whole object. So that if one synchronized method of an object is called, all other synchronized methods of the same object will wait.
As you stay in your waitFor method until value becomes less than 0 and your signal method is waiting for the other sync method to complete, it deadlocked itself.
Try using getters and setters for your value and have them synchronize. That way only the actual access is synchronized and not the wait loop as well.
as you are using
while(value < 0)
wait();
in your latter implementation, it is within an non-ending loop for value <0 and it is looping here for ever.
This may be a pointer of your deadlock situation.
Q1. What is a condVar in Java? If I see the code below, does a condition variable necessarily have to be within the 'mutex.acquire()' and 'mutex.release()' block?
public void put(Object x) throws InterruptedException {
mutex.acquire();
try {
while (count == array.length)
notFull.await();
array[putPtr] = x;
putPtr = (putPtr + 1) % array.length;
++count;
notEmpty.signal();
}
finally {
mutex.release();
}
}
I have three threads myThreadA, myThreadB, myThreadC running which call the same function commonActivity() which triggers the function myWorkReport() e.g.
public void myWorkReport(){
mutexMyWork.acquire();
try{
while(runMyWork){
doWork();
conditionMyWork.timedwait(sleepMyWork);
}
}
finally{
mutexMyWork.release()
}
}
public void commonActivity(){
try{
conditionMyWork.signal();
}finally{
//cleanup
}
}
public void myThreadA(){
mutexA.acquire();
try{
while(runningA){ //runningA is a boolean variable, this is always true as long as application is running
conditionA.timedwait(sleepA);
commonActivity();
}
}
finally{
mutexA.release();
}
}
public void myThreadB(){
mutexB.acquire();
try{
while(runningB){ //runningB is a boolean variable, this is always true as long as application is running
conditionB.timedwait(sleepB);
commonActivity();
}
}
finally{
mutexB.release();
}
}
public void myThreadC(){
mutexC.acquire();
try{
while(runningC){ //runningC is a boolean variable, this is always true as long as application is running.
conditionC.timedwait(sleepC);
commonActivity();
}
}
finally{
mutexC.release();
}
}
Q2. Is using timedwait a good practice. I could have achieved the same by using sleep(). If using sleep() call is bad, Why?
Q3. Is there any better way to do the above stuff?
Q4. Is it mandatory to have condition.signal() for every condition.timedwait(time);
Q1) The best resource for this is probably the JavaDoc for the Condition class. Condition variables are a mechanism that allow you to test that a particular condition holds true before allowing your method to proceed. In the case of your example there are two conditions, notFull and notEmpty.
The put method shown in your example waits for the notFull condition to become true before it attempts to add an element into the array, and once the insertion completes it signals the notEmpty condition to wake up any threads blocked waiting to remove an element from the array.
...does a condition variable necessarily
have to be within the
'mutex.acquire()' and
'mutex.release()' block?
Any calls to change the condition variables do need to be within a synchronized region - this can be through the built in synchronized keyword or one of the synchronizer classes provided by the java.util.concurrent package such as Lock. If you did not synchronize the condition variables there are two possible negative outcomes:
A missed signal - this is where one thread checks a condition and finds it does not hold, but before it blocks another thread comes in, performs some action to cause the condition to become true, and then signals all threads waiting on the condition. Unfortunately the first thread has already checked the condition and will block anyway even though it could actually proceed.
The second issue is the usual problem where you can have multiple threads attempting to modify the shared state simultaneously. In the case of your example multiple threads may call put() simultaneously, all of them then check the condition and see that the array is not full and attempt to insert into it, thereby overwriting elements in the array.
Q2) Timed waits can be useful for debugging purposes as they allow you to log information in the event the thread is not woken up via a signal.
Using sleep() in place of a timed wait is NOT a good idea, because as mentioned above you need to call the await() method within a synchronized region, and sleep() does not release any held locks, while await() does. This means that any sleeping thread will still hold the lock(s) they have acquired, causing other threads to block unnecessarily.
Q4) Technically, no you don't need to call signal() if you're using a timed wait, however, doing so means that all waits will not return until the timeout has elapsed, which is inefficient to say the least.
Q1:
A Condition object is associated (and acquired from) a Lock (aka mutext) object. The javadoc for the class is fairly clear as to its usage and application. To wait on the condition you need to have acquired the lock, and it is good coding practice to do so in a try/finally block (as you have). As soon as the thread that has acquired the lock waits on a condition for that lock, the lock is relinquished (atomically).
Q2:
Using timed wait is necessary to insure liveness of your program in case where the condition you are waiting for never occurs. Its definitely a more sophisticated form, and it is entirely useless if you do not check for the fact that you have timed out and take action to handle the time out condition.
Using sleep is an acceptable form of waiting for something to occur, but if you are already using a Lock ("mutex") and have a condition variable for that lock, it make NO sense not to use the time wait method of the condition:
For example, in your code, you are simply waiting for a given period but you do NOT check to see if condition occurred or if you timed out. (That's a bug.) What you should be doing is checking to see if your timed call returned true or false. (If it returns false, then it timed out & the condition has NOT occured (yet)).
public void myThreadA(){
mutexA.acquire();
try{
while(runningA){ //runningA is a boolean variable
if(conditionA.await (sleepATimeoutNanos))
commonActivity();
else {
// timeout! anything sensible to do in that case? Put it here ...
}
}
}
finally{
mutexA.release();
}
}
Q3: [edited]
The code fragments require a more detailed context to be comprehensible. For example, its not entirely clear if the conditions in the threads are all the same (but am assuming that they are).
If all you are trying to do is insure commonActivity() is executed only by one thread at a time, AND, certain sections of the commonActivity() do NOT require contention control, AND, you do require the facility to time out on your waits, then, you can simply use a Semaphore. Note that sempahore has its own set of methods for timed waits.
If ALL of the commonActivity() is critical, AND, you really don't mind waiting (without timeouts) simply make commonActivity() a synchronized method.
[final edit:)]
To be more formal about it, conditions are typically used in scenarios where you have two or more thread co-operating on a task and you require hand offs between the threads.
For example, you have a server that is processing asynchronous responses to user requests and the user is waiting for fulfillment of a Future object. A condition is perfect in this case. The future implementation is waiting for the condition and the server signals its completion.
In the old days, we would use wait() and notify(), but that was not a very robust (or trivially safe) mechanism. The Lock and Condition objects were designed precisely to address these shortcomings.
(A good online resource as a starting point)
Buy and read this book.
Q1. Condition variables are part of monitors facility which is sometimes used for threads synchronization. I don't recognize this particular implementations but usually conditional variables usage must be done in the critical section, thus mutex.acquire and release are required.
Q2. timedwait waits for signal on condition variable OR time out and then reqcquires critical section. So it differs from sleep.
Q3. I am not sure, but I think you may use built-in monitors functionality in java: synchronized for mutual exclusion and wait and notify instead of cond vars. Thus you will reduce dependencies of your code.
Q1. I think documentation gives quite good description. And yes, to await or signal you should hold the lock associated with the condition.
Q2. timedWait is not in Condition API, it's in TimeUnit API. If you use Condition and want to have a timeout for waiting use await(long time, TimeUnit unit). And having a timeout is generally a good idea - nobody wants a program to hang forever - provided you know what to do if timeout occurs.
Sleep is for waiting unconditionally and await is for waiting for an event. They have different purposes.
Q3. I don't know what this code is expected to do. If you want to perform some action cyclically, with some break between each iteration, use sleep instead of conditions.
Q4. As I wrote above conditions don't have timedwait method, they have await method. And calling await means you want to wait for some event to happen. This assumes that sometimes this event does happen and someone signals this. Right?
Q1. I believe by "condition variable", you're referring to something you check to determine the condition that you waited on. For example - if you have the typical producer-consumer situation, you might implement it as something like:
List<T> list;
public T get()
{
synchronized (list)
{
if (list.get(0) == null)
{
list.wait();
}
return list.get(0);
}
}
public void put(T obj)
{
synchronized (list)
{
list.add(obj);
list.notify();
}
}
However, due to the potential of spurious thread wakeups, it is possible for the consumer method to come out of the wait() call while the list is still empty. Thus it's good practice to use a condition variable to wait/sleep/etc. until the condition is true:
while (list.get(0) == null)
{
list.wait();
}
using while instead of if means that the consumer method will only exit that block if it definitely has something to return. Broadly speaking, any sleep or wait or blocking call that was triggered by a condition, and where you expect the condition to change, should be in a while block that checks that condition every loop.
In your situation you're already doing this with the while (count == array.length) wrapper around notFull.await().
Q2. Timed wait is generally a good practice - the timeout allows you to periodically perform a sanity check on your environment (e.g. has a shutdown-type flag been flipped), whereas a non-timed wait can only be stopped by interruption. On the other hand, if the wait is going to just keep blocking anyway until the condition is true, it makes little difference it it wakes up every 50 ms (say) until the notify() happens 2 seconds later, or if it just blocks constantly for those 2 seconds.
As for wait() vs sleep() - the former is generally preferable, since it means you get woken up as soon as you are able to take action. Thread.sleep(500) means that this thread is definitely not doing anything for the next 500ms, even if the thing it's waiting for is ready 2ms later. obj.wait(500) on the other hand would have been woken up 2ms into its sleep and can continue processing. Since sleeps introduce unconditional delays in your program, they're generally a clunkier way to do anything - they're only suitable when you're not waiting on any specific condition but actually want to sleep for a given time (e.g. a cleanup thread that fires every 60 seconds). If you're "sleeping" because you're waiting for some other thread to do something first, use a wait() (or other synchronous technique such as a CountDownLatch) instead.
Q3. Pass - it looks like there's a lot of boilerplate there, and since the code doesn't have any comments in and you haven't explained what it's supposed to do and how it's meant to behave, I'm not going to try and reverse-engineer that from what you're written. ;-)