Can't understand this multi-threading exception behavior - java

According to the documentation for ReentrantLock.newCondition(), the calling thread needs to own a lock before calling a signaling method:
If this lock is not held when any of the Condition waiting or signalling methods are called, then an IllegalMonitorStateException is thrown.
Indeed, this is what I see when I try it:
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signalAll(AbstractQueuedSynchronizer.java:1954)
at PingPongPrinter_.printPing(PingPong2.java:35)
at WorkerPing.run(PingPong2.java:53)
at java.lang.Thread.run(Thread.java:748)
So why do this restriction exists in java.util.concurrent.locks.ReentrantLock? I believe there is no such restriction in C++.

Answer to original question
You're unlocking a lock associated with the condition before signaling it.
From documentation:
An implementation may (and typically does) require that the current thread hold the lock associated with this Condition when this method is called. Implementations must document this precondition and any actions taken if the lock is not held. Typically, an exception such as IllegalMonitorStateException will be thrown.
Also, only lock for the time required to modify the value you are conditioning for.
void printPong() throws Exception {
// wait for pong condition
while (isPing) {
blockPong.await();
}
rlock.lock();
isPing = true; // modify value
blockPing.signalAll(); // signal ping
rlock.unlock();
System.out.println("Pong");
}
void printPing() throws Exception {
// wait for ping condition
while (!isPing) {
blockPing.await();
}
rlock.lock();
isPing = false; // modify value
blockPong.signalAll(); // signal pong
rlock.unlock();
System.out.println("Ping");
}
Answer to modified question
So why do this restriction exists in java.util.concurrent.locks.ReentrantLock? I believe there is no such restriction in C++.
Because ReentrantLock is mutually exclusive. It provides access to one single thread at any given time. That's a design choice.
In C++ the std::condition_variable also requires you to own a mutex to the resource in order to signal.

Related

Guarded Suspension in Java

Based on tutorials online, I have come up with below code of guarded suspension.
public synchronized String method1() throws InterruptedException {
lock = true;
Thread.sleep(17000);
lock = false;
notifyAll();
return "Method1";
}
public synchronized String method2() throws InterruptedException {
while(lock) {
wait();
}
Thread.sleep(3000);
return "From Method 2";
}
Above two methods are called at the same time from multiple threads.
From the above example, Does that lock variable used in the pre-condition for wait() ever be true ?
because with use of synchronized keyword, both methods are executed mutually exclusively.
Is the above example correct for Guarded suspension ?
When do we need Guarded Suspension ?
The Java keyword synchronized used on an instance method does ensure that only one thread at a time will execute any method on that single instance having the method modifier synchronized as well. More precise: not only on any method but on any resource / data using the same instance as a monitor or semaphore for mutual exclusively access control.
In your example, both instance methods have the modifier synchronized and hence will ensure only one thread is executing code inside any of those methods at any given time.
The variable lock is of no use in your example, because the same method which sets it to true does change it back to false. Hence method2 will never observe lock to be true.
Whenever more than one thread have to operate on a mutable resource and both threads should agree on the state read / operated, you have to protect this resource from racing conditions (read or modified concurrently). Otherwise the result may be different if executed by a single thread.
I think, your implementation is incorrect because you are doing lock = true; and lock = flase; in the same method.
In my opinion, it has to be done like below,
public synchronized String method1() throws InterruptedException {
Thread.sleep(17000);
lock = false;
notifyAll();
return "Method1";
}
public synchronized String method2() throws InterruptedException {
while(lock) {
wait();
}
Thread.sleep(3000);
lock = true;
return "From Method 2";
}
You have to understand that Guarded Suspension is a pattern when you have a situation where a precondition also needs to be satisfied in addition to synchronization lock being available.
e.g. when going to implement a thread-safe blocking queue, we need to put take() method thread on wait state if no items are available and put method thread also on wait state if queue is full. So this requirement is there in addition to synchronized access i.e. queue needs to be accessed in mutual exclusive way ( that is a primary requirement so you put synchronized on method signature ) but if queue is not in a proper state( by checking precondition variable) , you do wait or notify etc.
You have to also keep in mind that Thread.sleep(...) doesn't releases synchronization lock while Object.wait() does.
Take a real - life example ( like that of a thread - safe blocking queue ) then we can tell if your implementation is correct or not - its not possible to tell if your implementation is correct or not ( other than pointing that lock shouldn't be set / reset in same method ) since there is no generic implementation of this pattern.
Refer This
Hope it helps !!

Guarded blocks -- notifyAll() vs interrupt()

This Q looks for verification and/or comments/opinions the following:
The example on Guarded Blocks is as follows:
public synchronized void guardedJoy() {
// This guard only loops once for each special event, which may not
// be the event we're waiting for.
while(!joy) {
try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("Joy and efficiency have been achieved!");
}
The other end of this code-- the one setting joy properly is something like this:
public void setJoy2(TheClass t) {
synchronized (t) {
t.joy = true;
t.notifyAll();
}
}
The above does the "signaling" on joy by the use of notify().
An alternative is managing this "signalling" by interrupt():
public void guardedJoy2() {
// This guard only loops once for each special event, which may not
// be the event we're waiting for.
while(!joy) {
synchronized(this) {
try {
wait();
} catch (InterruptedException e) {}
}
}
System.out.println("Joy and efficiency have been achieved!");
}
and the one setting joy and letting the thread waiting for it is:
public void setJoy2(TheClass t) {
t.joy = true;
t.interrupt();
}
I'm looking to make a comparison between the two-- setJoy() and setJoy2().
First of all, guardedJoy2() above can "hear" both setJoy() and setJoy2() properly-- can see when joy is set and act the way it is expected to(?)
How does guardedJoy2() compare to guardedJoy()?
It achieves does the same thing as guardedJoy()-- i might be missing something, but i'm not seeing a difference in the outcome. The only difference is that guardedJoy2() released the lock of this from within the loop, and someone else acquire it before the method terminates for some unexpected results. Setting that aside (i.e., assuming that this is the only place where the use of joy and its side effects appear in the code), there's not difference between guardedJoy() and guardedJoy2()(?)
guardedJoy2() responds to both setJoy() and setJoy2().
It can "hear" from setJoy() when it is done, re-acquires its lock and go from there.
And, it can "hear" from setJoy2()-- by receiving the interrupt and thus throwing InterruptedException to get out of wait(), that's also the end of synch'd statement, checks to see in while condition that joy is set and goes from there. If the interrupt was from "someone" else and not from the one setting joy, gets into the loop again the same way till joy is set.
When, wait() is invoked and thus the lock of this is released in guardedJoy2(),
some other thread can get in by acquiring this lock and do things that are not supposed to be done till joy is set and guardedJoy2() is supposed to return properly. However, setting this aside (again, assuming this isn't an issue-- the only thing being looked for is seeing that message on the last line of guardedJoy2() on the console.) This-- setJoy2() can be preferable in cases where other things can be done on the object while it's getting its joy set and go from there (in setJoy2(), the thread setting joy doesn't have to have the lock of the object to interrupt it while setJoy() should have that lock to invoke notifyAll() on it).
How does guardedJoy2() & setJoy2() compare to guardedJoy() & setJoy() above?
TIA.
I'm going of the assumption that you meant just notify() in your first setJoy rather than notifyAll().
First, it's important to note that if you're invoking interrupt() on an expression of type TheClass, then TheClass is a subclass of Thread. This goes against a number of -recommendations that state that you should use Runnable instances to encapsulate the logic to be run on a thread rather than subclassing the class Thread. The javadoc of Thread#join(int) also states
It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
This is because some implementations of Java use those methods to handle thread logic behind the scenes. If you do not know that implementation logic and use these methods with Thread instances, you might get undesired behavior.
Then, and this might warrant some profiling, throwing (creating) an exception is an expensive operation, probably more so than removing a Thread from an object's wait set. What's more, exceptions should be used for exceptional conditions, not to guide your application logic.
I was going to say that your second example's synchronization order may be incorrect (assuming joy was not volatile) because the read in the guardedJoy2 loop might not see the write in setJoy2. However, the Java Language Specification states
If thread T1 interrupts thread T2, the interrupt by T1
synchronizes-with any point where any other thread (including T2)
determines that T2 has been interrupted (by having an
InterruptedException thrown or by invoking Thread.interrupted or
Thread.isInterrupted)
So you still have visibility guarantees in place.

Why must wait and notify be called from synchronized block/method? [duplicate]

This question already has answers here:
Why must wait() always be in synchronized block
(10 answers)
Closed 9 years ago.
In the book I'm reading it says:
This technique is needed due to a race condition that would otherwise
exist between setting and sending the notification and testing and
getting the notification. If the wait() and notify() mechanism were
not invoked while holding the synchronization lock, there would be no
way to guarantee that the notification would be received.
Don't understand what this exactly means, why can the race condition happen?
EDIT: Hmmmm, I see now that this is possibly a duplicate question of Why must wait() always be in synchronized block
, but it seams that the answers focus on making the condition check and going to wait synchronized.
Counterexample from shrini1000:
I can still do something like:
while(!condition) { synchronized(this) { wait(); } }
which means there's still a race between checking the condition and waiting even
if wait() is correctly called in a synchronized block. So is there
any other reason behind this restriction, perhaps due to the way it's
implemented in Java?
It must be all about the technique author must have presented before the article you have copied in question. I am not sure which book you are reading but I will try to answer this question.
I read a similar book "Thinking in Java" that talked about the same race condition. It suggests that this can be prevented using wait and notify so that the code doesn't miss the notify signal.
When two threads are coordinated using notify( )/wait( ) or notifyAll(
)/wait( ), it’s possible to miss a signal. Suppose T1 is a thread that
notifies T2, and that the two threads are implemented using the
following (flawed) approach:
T1:
synchronized(sharedMonitor) {
<setup condition for T2>
sharedMonitor.notify();
}
T2:
while(someCondition) {
// Assume that T2 evaluates someCondition and finds
// it true, now when program goes to next line thread
// scheduler switches to T1 and executes notify again
// after when control comes to T2 it blindly executes
// wait(), but it has already missed notify so it will
// always be waiting.
.... some code ....
synchronized(sharedMonitor) {
sharedMonitor.wait();
}
}
The (setup condition for T2) is an action to prevent T2 from calling wait( ), if it hasn’t already.
The solution is to prevent the race condition over the someCondition variable. Here is the correct approach for T2:
synchronized(sharedMonitor) {
while(someCondition) {
sharedMonitor.wait();
}
}
The fact that something can be misused is hardly a counterexample.
Java only enforces that wait() and notify() are part of a synchronized block (since that's the only way they are supposed to be used), but it's up to you to define the block boundaries.
As a counter-counterexample, think about the finally block. Java only enforces that it comes after a try block, but you're the only one who should know what's supposed to go into that try block; you could even leave it empty (which would then miss the very point of finally).

A Mutex for inter-threading usages in Java?

I want a Mutex in Java which let me to wait on it in a thread and release it in another thread. I know that I can use a Semaphore with capacity of 1 but the problem is that the "acquire()" method throws "InterruptedException". Is there any special synchronization way for this purpose in Java?
Luckily, Semaphore provides this method for you :)
public void acquireUninterruptibly()
Acquires a permit from this semaphore, blocking until one is
available. Acquires a permit, if one is available and returns
immediately, reducing the number of available permits by one.
If no permit is available then the current thread becomes disabled for
thread scheduling purposes and lies dormant until some other thread
invokes the release() method for this semaphore and the current thread
is next to be assigned a permit.
If the current thread is interrupted while waiting for a permit then
it will continue to wait, but the time at which the thread is assigned
a permit may change compared to the time it would have received the
permit had no interruption occurred. When the thread does return from
this method its interrupt status will be set.
InterruptedException is not an issue, just wrap it in a loop:
while(true) {
try {
semaphore.acquire();
break;
} catch(InterruptedException e) {
//swallow, continue;
}
}
However this code is not very safe and elegant, but will work providing that you "want to make sure you can acquire a permit!"
if you have a code in which a thread is going to wait then you will definitely have to handle interrupted exception unless you are using synchronized block. Also, What is the problem with interrupted exception?
ThreadA
volatile boolean waitCondition = true
synchronized(lockObject) {
while (waitContidion) {
lockObject.wait();
}
}
ThreadB
synchronized(lockObject) {
waitCondition = false;
lockObject.notifyAll();
}
or use Condition/Signal on Lock instances.
Correct handling of InterruptedException is very important, at least you must set it's interrupted flag with Thread.currentThread().interrupt() method in catch block.

What does synchronized()/wait()/notifyAll() do in Java? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java Synchronization
I'm reading the book Beginning Android Games.
It uses synchronized() a lot but I don't really understand what it does. I haven't used Java in a long time and I'm not sure if I ever used multithreading.
In the Canvas examples it uses synchronized(this). However in the OpenGL ES example, it creates an Object called stateChanged and then uses synchronized(stateChanged). When the game state changes it calls stateChanged.wait() and then stateChanged.notifyAll();
Some code:
Object stateChanged = new Object();
//The onPause() looks like this:
public void onPause()
{
synchronized(stateChanged)
{
if(isFinishing())
state = GLGameState.Finished;
else
state = GLGameState.Paused;
while(true)
{
try
{
stateChanged.wait();
break;
} catch(InterruptedException e)
{
}
}
}
}
//The onDrawSurface looks like this:
public void onDrawFrame(GL10 gl)
{
GLGameState state = null;
synchronized(stateChanged)
{
state = this.state;
}
if(state == GLGameState.Running)
{
}
if(state == GLGameState.Paused)
{
synchronized(stateChanged)
{
this.state = GLGameState.Idle;
stateChanged.notifyAll();
}
}
if(state == GLGameState.Finished)
{
synchronized(stateChanged)
{
this.state = GLGameState.Idle;
stateChanged.notifyAll();
}
}
}
//the onResume() looks like this:
synchronized(stateChanged)
{
state = GLGameState.Running;
startTime = System.nanoTime();
}
The synchronized keyword is used to keep variables or methods thread-safe. If you wrap a variable in a synchronized block like so:
synchronized(myVar) {
// Logic involing myVar
}
Then any attempts to modify the value of myVar from another thread while the logic inside the synchronized block is running will wait until the block has finished execution. It ensures that the value going into the block will be the same through the lifecycle of that block.
This Java Tutorial can probably help you understand what using synchronized on an object does.
When object.wait() is called it will release the lock held on that object (which happens when you say synchronized(object)), and freeze the thread. The thread then waits until object.notify() or object.notifyAll() is called by a separate thread. Once one of these calls occurs, it will allow any threads that were stopped due to object.wait() to continue. This does not mean that the thread that called object.notify() or object.notifyAll() will freeze and pass control to a waiting thread, it just means these waiting threads are now able to continue, whereas before they were not.
When used like this:
private synchronized void someMehtod()
You get these effects:
1. First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
2. Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
(Taken from here)
You get a similar effect when you use a synchronized block of code:
private void someMethod() {
// some actions...
synchronized(this) {
// code here has synchronized access
}
// more actions...
}
As explained here
Java (which Android is based on) can run under multiple threads that can utilize multiple cpu cores. Multi-threading means that you can have Java doing two processes at the exact same moment. If you have a block of code or method that you need to ensure can only be operated by one thread at a time, you synchronize that block of code.
Here is the official Java explanation from Oracle
It's important to know that there is a processor/io costs involved with using synchronized and you only want to use it when you need it. It is also important to research what Java classes/methods are thread safe. For instance, the ++ increment operator is not guarateed to be thread safe, whereas you can easily create a block of synchronized code that increments a value using += 1.
only one thread can be active and inside block synchronized by given object.
calling wait stops gives up this right and deactivates current thread until someone call notify(all)()
Then the inactive thread start wanting to run in the synchronized block again, but is treated equaly with all other threads that wants it. Only one somehow chosen (programmer cannot influence nor depend on which one) actualy gets there.
Synchronized keyword in java is used for 2 things.
First meaning is so called critical section, i.e. part of code that can be accessed by one thread simultaneously. The object you pass to synchronized allows some kind of naming: if one code is run in synchronized(a) it cannot access other block that is into synchronized(a) but can access block of code into synchronized(b).
Other issue is inter-thread communication. Thread can wait until other thread notifies it. Both wait and notify must be written into synchronized block.
It was a very short description. I'd suggest you to search for some tutorial about multithreading and read it.
The keyword synchronized, together with the wait and notify operations form a nonblocking condition monitor, a construct useful for coordinating multiple threads.

Categories

Resources