Condition - should unlock before await? - java

Could you tell me if I should release lock before await on condition?
try {
lock.lock();
while (isNotEmpty()) {
condition.await();
}
} finally {
lock.unlock();
}
Or
try {
lock.lock();
while (isNotEmpty()) {
lock.unlock();
condition.await();
}
} finally {
lock.unlock();
}

No, you do not need to explicitly release the lock before calling await, await will release it automatically. From javadoc:
The lock associated with this Condition is atomically released and the
current thread becomes disabled for thread scheduling purposes[...]
And:
The current thread is assumed to hold the lock associated with this Condition when this method is called.

You can only await() on a Condition when you have lock()ed the associated Lock
Why don't you have a condition for isEmpty to make your conditions clearer.
See the example in the Javadoc. http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html
e.g.
lock.lock();
try {
while (count > 0)
isEmpty.await();
// do something when empty.
} finally {
lock.unlock();
}

wait and notify must be called from with in the synchronized block, so the same rule applies for await and signal. Though await releases automatically, but if you do it should be between lock() and unlock()
lock.lock() // start of synchronized block
condition.await()
lock.unlock() // end of synchronized block

Related

How to Detect a Spurious Wakeup

I have read many posts on this. This answer https://stackoverflow.com/a/6701060/2359945 claimed a 100 bounty by suggesting to test the interrupted flag.
I tested this, and it does not work for me. So, the question remains, how do I detect a spurious wakeup, or is it not possible? Thank you.
class TestSpuriousWakeup {
static Thread t1, tInterrupt, tNotify;
// spawn one thread that will be interrupted and be notified
// spawn one thread that will interrupt
// spawn one thread that will notify
public static void main(String[] args) {
System.out.println("*** main Starting");
initThreads();
try {
t1.start();
Thread.sleep(2000);
tNotify.start();
tNotify.join();
Thread.sleep(2000);
tInterrupt.start();
tInterrupt.join();
t1.join();
} catch (InterruptedException e) {
System.out.println("*** Unexpected interrupt in main");
}
System.out.println("*** main Ended.");
}
private static void initThreads() {
t1 = new Thread() {
#Override
public void run() {
System.out.println("ThreadInterruptMe Started ...");
boolean stop = false;
Thread.interrupted(); // clear the interrupted flag
while (!stop) {
try {
System.out.println("ThreadInterruptMe Sleeping 5000ms ...");
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("ThreadInterruptMe InterruptedException e!");
System.out.println("ThreadInterruptMe e.getCause => " + e.getCause());
System.out.println("ThreadInterruptMe e.getLocalizedMessage => " + e.getLocalizedMessage());
stop = Thread.interrupted();
if (stop) {
System.out.println("ThreadInterruptMe was INTERRUPTED because Thread.interrupted() is true"); // never happens
} else {
System.out.println("ThreadInterruptMe was NOTIFIED because Thread.interrupted() is false"); // always happens
}
} finally {
Thread.interrupted(); // clear the interrupted flag
System.out.println("ThreadInterruptMe InterruptedException finally");
}
}
System.out.println("ThreadInterruptMe Ended.");
}
};
tInterrupt = new Thread() {
#Override
public void run() {
System.out.println(" ThreadInterruptYou Started ... interrupting now!");
t1.interrupt();
System.out.println(" ThreadInterruptYou Ended.");
}
};
tNotify = new Thread() {
#Override
public void run() {
System.out.println(" ThreadNotifyYou Started ... notifying now!");
t1.interrupt();
System.out.println(" ThreadNotifyYou Ended.");
}
};
}
}
Output:
*** main Starting
ThreadInterruptMe Started ...
ThreadInterruptMe Sleeping 5000ms ...
ThreadNotifyYou Started ... notifying now!
ThreadInterruptMe InterruptedException e!
ThreadNotifyYou Ended.
ThreadInterruptMe e.getCause => null
ThreadInterruptMe e.getLocalizedMessage => sleep interrupted
ThreadInterruptMe was NOTIFIED because Thread.interrupted() is false
ThreadInterruptMe InterruptedException finally
ThreadInterruptMe Sleeping 5000ms ...
ThreadInterruptYou Started ... interrupting now!
ThreadInterruptMe InterruptedException e!
ThreadInterruptMe e.getCause => null
ThreadInterruptMe e.getLocalizedMessage => sleep interrupted
ThreadInterruptMe was NOTIFIED because Thread.interrupted() is false
ThreadInterruptMe InterruptedException finally
ThreadInterruptMe Sleeping 5000ms ...
ThreadInterruptYou Ended.
ThreadInterruptMe InterruptedException finally
ThreadInterruptMe Sleeping 5000ms ...
ThreadInterruptMe InterruptedException finally
ThreadInterruptMe Sleeping 5000ms ...
<infinite loop>
What spurious wakeups are not
sleep() is not subject to spurious wakeups. The low-level system call it uses to sleep may be, but Java takes care of this detail for you, re-entering the system call if it's woken up prematurely. As a user you are not exposed to spurious wakeups.
Spurious wakeups are also unrelated to thread interruption. That is a separate tool. Threads are never "spuriously interrupted". If your thread is interrupted, that means somebody somewhere called Thread.interrupt() on your thread. Find that code and you will have the culprit.
What spurious wakeups are
If you want to test spurious wakeups, run tests with Object.wait() instead, since that's the classic method that suffers from them.
The naïve way of using wait() is to simply call it, expecting that it will only return when some other thread calls notify(). For example, a message sending loop might be:
for (;;) {
synchronized (monitor) {
if (queue.isEmpty()) { // incorrect
monitor.wait();
}
}
send(queue.remove());
}
This will fail if wait() spuriously wakes up without a message having been added to the queue. The solution is to add a loop around the wait() to verify the condition every time the thread is woken up.
for (;;) {
synchronized (monitor) {
while (queue.isEmpty()) { // correct
monitor.wait();
}
}
send(queue.remove());
}
The simplest way to simulate a spurious wakeup, then, is to simply call notify() without changing the loop condition.
synchronized (monitor) {
monitor.notify();
}
This will have the exact same effect on the thread performing wait() as if it encountered a spurious wakeup. The incorrect code using if won't realize the queue is still empty and will crash. The correct code using while will re-check the condition and safely re-enter the wait() call.
You detect a spurious wakeup by re-testing the predicate.
A wakeup is spurious if there is no reason for the wakeup. A wakeup is not spurious if some other thread intentionally woke you.
Or, to put it even more simply: If the thing you were waiting for hasn't happened, the wakeup was spurious. If the thing you were waiting for has happened, the wakeup was not spurious. You have to be able to check whether the thing you were waiting or has happened or not -- otherwise, how did you know you had to wait for it in the first place?
So before a thread intentionally wakes you, have it set some synchronized variable that you check when you wake up. If that variable is set, then the wakeup was not spurious, and you clear the flag. If it is not set, then the wakeup was spuroius, and you typically ignore the wakeup.
So, the flow goes as follows:
To wake/signal/interrupt at thread:
Acquire a lock or enter a synchronized block.
Set the boolean predicate to true.
Wake the thread.
Release the lock or exit the synchronized block.
(If desired, the order of 3 and 4 can be swapped.)
To wait for something to happen:
Acquire a lock or enter a synchronized block.
Set the boolean predicate to false (or check it if it was already set).
Wait, releasing the lock. When woken, reacquire the lock (or re-enter a synchronized block).
Check the predicate to see if the wake is spurious. If the predicate is false, go to step 3.
You now know the wakeup was not spurious. Release the lock or exit the synchronized block.

waiting threads in a syncronized block

if i have these functions
public void methodA(){
synchronized (ObjectAlwaysDifferent) {
....
}
}
public void methodB(){
}
And threads that can enter inside the synchronized block so,
Thread1 enter with Object1
Thread2 enter with Object2
and another thread
Thread3 want to enter with Object1
if thread loop is:
public void run(){
while(true){
methodA();
methodB();
}
}
thread3 will wait inside the methodA,until the lock of object1 will released?
or it ' s able to go to execute the methoB if it's monitor object is locked by another thread?
it is possible to rewrite the methodA() using Lock and condition of (concurrent API)?
Yes, Thread3 would wait until lock gets released.
You are looking for tryLock() from Lock interface
From docs :
boolean tryLock()
Acquires the lock only if it is free at the time of invocation.
Acquires the lock if it is available and returns immediately with the value true. If the lock is not available then this method will return immediately with the value false.
A typical usage idiom for this method would be:
Lock lock = ...;
if (lock.tryLock()) {
try {
// manipulate protected state
} finally {
lock.unlock();
}
} else {
// perform alternative actions
}
This usage ensures that the lock is unlocked if it was acquired, and doesn't try to unlock if the lock was not acquired.
Returns:
true if the lock was acquired and false otherwise

What is the purpose of using synchronized (Thread.currentThread())?

Can any one please elaborate why the below code snippet gives IllegalMonitorStateException? I still can't able to find why and when this exception occurs and what is the purpose to lock on the current executing thread instead of object?
void waitForSignal() {
Object obj = new Object();
synchronized (Thread.currentThread()) {
obj.wait();
obj.notify();
}
}
In order to call wait on obj that method/code block should synchronised on obj
void waitForSignal() {
Object obj = new Object();
synchronized (obj) {
obj.wait();
obj.notify();
}
}
You are getting that exception because you need to acquire lock on obj before calling wait(), notify() or notifyAll() methods. These methods are designed to provide a mechanism to allow a thread to block until a specific condition is met.
The wait() method releases lock on the object, that mean you need to have acquired a lock before releasing it.
Whereas notify() and notifyAll() are to notify other threads which are waiting to acquire lock on the same object. It's like one thread is telling other threads : "Dudes, I don't need the object for now, you can go ahead and use it. Make sure you notify me once you are done.".
There are no real scenario where you would want to acquired lock on thread it self.
Here's a code block where you wait for thread to complete before executing a code block.
Thread t = new Thread() {
public void run() {
synchronized (Thread.currentThread()) {
System.out.println("Thread");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
}
};
t.start();
Thread.sleep(10);//sleep main thread
synchronized (t) {
System.out.println("Main Thread");
}
}
I have to sleep main thread becaue, Most of the time synchronized block acquires lock before the thread it self.
You can do the same with join()
synchronized (Thread.currentThread())
doesnt make any sense, a thread cant synchronize itself (that'd produce a deadlock), you will have to synchronize on the OBJECT YOU ARE WAITING FOR:
synchronized (obj)
Also : its always better to use semaphore for this kind of job
Generally speaking locking on the thread makes no sense except for blocking operations on the Thread object itself. For example Thread.join() wait()s on the Thread to finish. This means it uses a synchronised block with wait() to wait on the thread itself.

Need to semaphore.relase() if semaphore.acquire() gets InterruptedException?

From the Java java.util.concurrent.Semaphore docs it wasn't quite clear to me what happens if semaphore.acquire() blocks the thread and later gets interrupted by an InterruptedException. Has the semaphore value been decreased and so is there a need to release the semaphore?
Currently I am using code like this:
try {
// use semaphore to limit number of parallel threads
semaphore.acquire();
doMyWork();
}
finally {
semaphore.release();
}
Or should I rather not call release() when an InterruptedException occurs during acquire() ?
call release() when an InterruptedException occurs during acquire() ?
You should not. If .acquire() is interrupted, the semaphore is not acquired, so likely should not release it.
Your code should be
// use semaphore to limit number of parallel threads
semaphore.acquire();
try {
doMyWork();
}
finally {
semaphore.release();
}
nos's accepted answer is partially correct, except semaphore.acquire() also throws InterruptedException. So, to be 100% correct, the code would look like:
try {
semaphore.acquire();
try {
doMyWork();
} catch (InterruptedException e) {
// do something, if you wish
} finally {
semaphore.release();
}
} catch (InterruptedException e) {
// do something, if you wish
}
If the thread is interrupted before acquire method call, or while waiting to acquire a permit the InterruptedException will be thrown and no permit will be hold, so no need to release. Only when you are certain that a permit was acquired (after calling the acquire method call) you will need to release the permit. So you better acquire before your try block starts, something like:
sem.acquire();
try{
doMyWork();
}finally{
sem.release();
}

Behavior of a synchronized method with try and finally

Assume the following method:
public synchronized void a(){
try{
System.out.println("a");
return;
}finally{
System.out.println("a, finally");
}
}
I understand that the finally block will still be executed even after the return statement. One can even "override" the return value !
But my question is, will the method be unlocked after the return statement or after finally ?
Since return is not executed before finally block has finished, and because the entire method is synchronized, the lock is not released until after the finally block has finished.
If you need to release the lock on exception rather than on returning from the method, you can nest your synchronized block inside the try/finally block:
public void a(){
try {
synchronized (this) {
System.out.println("a");
return;
}
} finally{
System.out.println("a, finally");
}
}
1st of all finally will execute before the return statement....
Secondly the lock will be released only when the thread has finished executing the complete method.. ie(till the end braces of this method), Moreover this lock is of the object, so not only this method, but all the synchronized method in that class are locked.
yes it is. It'll wait up to return from function which happen after executing finally block execution.

Categories