Guarded blocks -- notifyAll() vs interrupt() - java

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.

Related

Java locking methods

How can I lock a method until an other method is invoked?
public class TestLock{
public void methodIsLockedAfterFirstCall(){
doSomething();
//now lockThisMethod (when invoked, the thread shall sleep)
}
public void methodToDoSomethingAfterTheFirstMethod(){
doSomeOtherThing()
//unlock the first Method?
}
}
Is there something already in Java for this or should I do it some way around ( e.g. Boolean or AtomicLong)?
If you want to build this up from base principles you'd do something like:
private final AtomicBoolean lock = new AtomicBoolean();
public void methodIsLockedAfterFirstCall() {
doSomething();
synchronized (lock) {
while (lock.getAndSet(true)) try {
lock.wait();
} catch (InterruptedException e) {
return; // SEE NOTE 1
}
}
}
public void methodToDoSomethingAfterTheFirstMethod() {
doSomeOtherThing();
synchronized (lock) {
lock.set(false):
lock.notifyAll();
}
}
This code:
Uses a private lock. Locking om something public is only acceptable if you document this behaviour and maintain this behaviour for future versions (or mark your new version as utterly incompatible with the old). As a rule, public locks are an error. synchronizing on this, therefore, is usually wrong. This code locks on a private variable.
This code does not run afoul of JMM issues by using AtomicBoolean.
NOTE 1: InterruptedException only ever occurs if you (or other code running on the JVM) explicitly calls .interrupt() on the thread (it does not occur if e.g. the user hits CTRL+C, or killall YourProcess, or 'end task' in the task manager, or any other way that doesn't involve code running in that VM that calls .interrupt(). What to do? Well, do not just e.printStackTrace(), the usual mainstay of java programmers who no idea what they are doing. What did you want to happen when you write thread.interrupt(), somewhere else in the codebase? Do that. If the notion of 'stop waiting for that second call now' is a sensible idea, then document the behaviour in this method. Here I've chosen to just return (stop waiting), but keep the lock in locked state.
Does not use notify/wait as a mechanism to communicate data; only as a mechanism to communicate when to wait and when to stop waiting. This is generally a good idea, it can be very hard to debug relevant state when that state is captured by 'were you notified or not', and makes it impossible to use the wait(timeout) variant. That's why there is a while loop. Being woken up just results in trying to getAndSet again, which can reuslt in waiting some more. That's a good thing.
Or, use something from j.u.concurrent. Some ideas:
A Lock which the first method locks and the second method unlocks.
A Semaphore doesn't sound right, as .release() will add 1 to the count, always, so if you call the second method whilst the 'lock status' is UNLOCKED, you'd erroneously be adding a permit. You can't do if (semaphore.availablePermits() < 1) semaphore.release(); as that'd have a race condition unless you do this in a synchronized block which kinda defeats the purpose.
There is a lot under the java.util.concurrent.locks and java.util.concurrent packages.
Maybe CountDownLatch is the easier one to use:
private final CountDownLatch latch = new CountDownLatch(1);
public class TestLock{
public void methodIsLockedAfterFirstCall() throws InterruptedException {
doSomething();
//now lockThisMethod (when invoked, the thread shall sleep)
latch.await()
}
public void methodToDoSomethingAfterTheFirstMethod(){
doSomeOtherThing()
//unlock the first Method?
latch.countDown();
}
}

what happen if using wait and notify methods not in a synchronized blocks ? is it useful?

Two questions regarding synchronization
What happen if using wait and notify methods in non synchronized blocks ? Is it useful ?
Should synchronized object be the same as the object of the wait method ? Can I do like this :
synchronized (o) {
try {
this.wait();
} catch (InterruptedException e) {
}
}
An IllegalThreadStateException is thrown if the current thread fails to synchronize on an object before calling its wait() or notify() methods. So, no, it isn't useful.
Yes, to reiterate the above, the thread must synchronize on the same instance upon which it invokes wait() or notify(). So the example will only work if o == this.
I don't find good reasons to use wait() and notify() since java.util.concurrent was introduced, and synchronized is less useful now too. I recommend the higher-level tools in that package to both beginners (as easier to use) and advanced (more powerful and correct) programmers.
1.
You can't call wait() or notify()/notifyAll() outside of synchronized blocks that synchronize on the the object the method calls belong to. If you try, you'll get an IllegalMonitorStateException.
2.
You are required to synchronize on the same object that your wait()/notify()/notifyAll() calls belong to. For instance, your code will throw an IMSE as written. You'll want to call synchronized(this){ ... instead.

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).

Non volatile status flag in multi-threaded code

I am a novice when it comes to concurrency and unsure of myself when spotting issues, I was looking through a fairly established code base and found the following code (edited for brevity) which I believe to be susceptible to data races:
public class Example extends Thread {
boolean condition = false;
public void run () {
while (true) {
synchronized (this) {
try {
while( condition ) wait();
}
catch (InterruptedException e) { /*for brevity*/ }
}
// non-blocking computation
}
}
public void setTrue () { condition = true; }
public void setFalse () {
synchronized (this) {
condition = false;
this.notifyAll();
}
}
}
As far as I understand condition must be volatile since even with the synchronized block, the compiler will not issue any memory barriers; if it were a volatile store to condition in setTrue the compiler would issue StoreEnter.
Am I right to believe the above is susceptible to data races? And if so how can I witness the data race through an example (as opposed to simply knowing the guarantees provided by the JMM). A simple test with threads randomly invoking setTrue in a loop doesn't uncover the data race.
Also, I believe the use of notifyAll is overkill here since there is one condition to check and only one thread will ever be waiting on it, right?
Thank you.
As far as I understand condition must be volatile since even with the synchronized block, the compiler will not issue any memory barriers; if it were a volatile store to condition in setTrue the compiler would issue StoreEnter.
That is not correct. When you use a shared variable within a synchronized block, your code will be thread-safe with respect to other threads using the same variable with the same lock. If memory barriers are required, then they will be used.
However, the code you have shown us is is incorrect because the setTrue() method is updating the flag outside of a synchronized block.
Am I right to believe the above is susceptible to data races?
Yea ... sort of. The scenario is as follows:
The condition is false.
Some other thread calls setTrue which sets the condition variable to true in its cache. But since the setTrue method doesn't use synchronized, there is no write barrier, and no flushing to main memory.
The "example" thread fetches the latest committed value from main memory (which is still false), and doesn't wait as it is supposed to do.
Also, I believe the use of notifyAll is overkill here since there is one condition to check and only one thread will ever be waiting on it, right?
It could be replaced with a notify() ... if that is what you mean. But to be honest, it makes no real difference which flavour of notify you use.
You commented:
I meant that the compiler would not consider it necessary to submit a memory barrier in this situation.
Maybe. But the "monitorenter" and "monitorexit" instructions implicitly involve memory barriers.
And:
Wouldn't it also be correct if condition were volatile?
If you are talking about using volatile AND synchronized, then yes it would be correct ... though the volatile would be redundant (assuming that the setTrue bug is fixed.)
If you are talking about volatile only, then no. You can't implement an efficient "wait on a condition variable" with just volatile. The problem is that neither the "read/test/wait" or "write/notify" sequences can be performed atomically; i.e. without the possibility of race-conditions.
And besides, you can't do the equivalent of wait/notify without using a primitive object mutex, or a Lock object.
Am I right to believe the above is susceptible to data races?
Don't think so. condition is unimportant, it only permits the method to avoid waiting. The way it is set is also not important. It doesn't need to be volatile, as it's use is local to one object.
Also, I believe the use of notifyAll is overkill here since there is
one condition to check and only one thread will ever be waiting on it,
right?
NotifyAll is fine, while there is only one thread waiting in the method there may be many other threads waiting on, or waiting for, the thread.

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