synchronized Boolean

S

shypen42

Hi group,

following the various advices given by Joshua Bloch
in Effective Java, I (try to) use synchronization for
reliable communication between threads.

Such advices are:

"You may hear it said that to improve performance, you
"should avoid the use of synchronization when reading
"or writing atomic data. This advice is dangerously
"wrong.

(which I think I understand pretty well)

or:

"The use of the volatile modifier constitutes a viable
"alternative to ordinary synchronization under certain
"circumstances, but this is an advanced technique.
"Furthermore, the extent of its applicability will not
"be known until the ongoing work on the memory model
"is complete.

(which looks more esoteric to me but forget it as of now)

So let's say I do /not/ want to use the volatile keyword.
My question is about the "synchronized" keyword, not
about "volatile".

In other words, I know that what follows can also be
done by using "volatile", but this is not related to my
question, for I'm trying to understand how
synchronization/locks are working.

Here's a short piece of code (supposed to be correctly
synchronized) shown in the book that is also seen very
often in various projects:

public void run() {
boolean done = false;

while (!stopRequested() && !done) {
...
}
}

public synchronized void requestStop() {
stop = true;
}

private synchronized boolean stopRequested() {
return stop;
}

Note that there may be other synchronized methods in
the class.

So far so good, it's working fine...

But wouldn't it be more effective to create, say, a
SynchedBoolean class looking like this:

public final class SynchedBoolean {

private boolean b;

public SynchedBoolean(final boolean b) {
this.b = b;
}

public boolean get() {
synchronized(this) {
return b;
}
}

public void set(final boolean b) {
synchronized(this) {
this.b = b;
}
}

...
}


then rewrite the example with the following code:

SynchedBoolean stopRequested;

public void run() {
boolean done = false;

while (!stopRequested.get() && !done) {
...
}
}

public synchronized void requestStop() {
stopRequested.set(true);
}


Isn't the second example "more gentle" by
acquiring a less intrusive lock?

I suppose that performance-wise I won't see
much differences, but /technically/, is there
a difference (synchronization-wise)?

thanks a lot for any information
 
G

Gordon Beaton

Isn't the second example "more gentle" by acquiring a less intrusive
lock?

I suppose that performance-wise I won't see much differences, but
/technically/, is there a difference (synchronization-wise)?

Your SynchedBoolean example has one technical advantage over the other
one: since it uses a separate lock object, it doesn't need to contend
with other synchronized methods in the main class. However since
you've kept requestStop() in the main class synchronized even when
using SynchedBoolean, the advantage is lost.

You could achieve a similar effect without the extra class by
declaring a special lock object in the main class, and explicitly
synchronizing on that in methods for setting and getting the value of
the stopRequested boolean. However the extra class encapsulates this
nicely and could also be used elswhere.

I notice that you use synchronized(this) explicitly in the
SynchedBoolean class, but when the entire method body is within the
synchronized block that's equivalent to simply specifying the methods
synchronized.

/gordon
 
R

Remon van Vliet

Gordon Beaton said:
Your SynchedBoolean example has one technical advantage over the other
one: since it uses a separate lock object, it doesn't need to contend
with other synchronized methods in the main class. However since
you've kept requestStop() in the main class synchronized even when
using SynchedBoolean, the advantage is lost.

You could achieve a similar effect without the extra class by
declaring a special lock object in the main class, and explicitly
synchronizing on that in methods for setting and getting the value of
the stopRequested boolean. However the extra class encapsulates this
nicely and could also be used elswhere.

I notice that you use synchronized(this) explicitly in the
SynchedBoolean class, but when the entire method body is within the
synchronized block that's equivalent to simply specifying the methods
synchronized.

/gordon


And to comment on your SynchedBoolean class, have a look at this
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/AtomicBoolean.html

Also, java.util.concurrent provides very elegant locking/concurrency
mechanisms that eliminate most needs for synchronized methods or blocks.

- Remon
 
I

Ingo R. Homann

Hi Remon,
Also, java.util.concurrent provides very elegant locking/concurrency
mechanisms that eliminate most needs for synchronized methods or blocks.

What do you mean with this? In my opinion, it is much easier to use
synchronized methods or blocks than to do the locking manually.

(I am aware that synchronized blocks are sometimes not flexible enogh,
so that is necessary to do locking manually, but that is a different
topic, and especially is no contradiction to what I just said...)

Ciao,
Ingo
 
S

shypen42

Gordon Beaton wrote:
....
Your SynchedBoolean example has one technical advantage over the other
one: since it uses a separate lock object, it doesn't need to contend
with other synchronized methods in the main class.

Ah excellent! This is exactly what I was thinking :)

However since
you've kept requestStop() in the main class synchronized even when
using SynchedBoolean, the advantage is lost.

Damn, my mistake and good catch... I made the error here
in my post, but not in my programs.

The whole point was of course to remove the "synchronized"
on that method in the main class.

You could achieve a similar effect without the extra class by
declaring a special lock object in the main class, and explicitly
synchronizing on that in methods for setting and getting the value of
the stopRequested boolean. However the extra class encapsulates this
nicely and could also be used elswhere.

Yup... I actually wrote that extra class after finding
myself repeating such code a few times.

:)

I notice that you use synchronized(this) explicitly in the
SynchedBoolean class, but when the entire method body is within the
synchronized block that's equivalent to simply specifying the methods
synchronized.

Correct! Code fixed asap ;)


Thanks a lot for your thoughtful reply,
 
S

shypen42

Remon van Vliet wrote:
....

Excellent... I wasn't aware of this. And that class maily does the
trick by encapsulating a boolean flag declared as... volatile!

(which I said I didn't want to use, but it was just to try to
understand a little bit better how synchronization works,
now I'll probably just use AtomicBoolean if/when I need such
a feature)

:)

thanks,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top