[concurrency-interest] Re: synchronized vs ReentrantLock semantic

Gregg Wonderly gregg at cytetech.com
Tue Jun 14 00:16:01 EDT 2005



David Holmes wrote:
> Gregg Wonderly wrote:
> 
>>Okay, then this is sure not clear to me either.  I guess I'm really
>>confused now.  I would suggest there should be some even more explicit
>>wording about all the specific steps and the specific ties into the
>>memory model.
> 
> Where has this confusion arisen?

I guess that I haven't remembered enough of what I've read, or perhaps I 
haven't read what I needed.  For some reason, I was under the impression 
that lock semantics were better optimizations then just the ability to 
create synchronized pieces of code that were not Java language blocks.
Clearly, I was day dreaming or something...  When I've used the 
monitorEnter and monitorExit JNI methods, I've thought about having more 
flexible control as Lock provides.  I guess I just throught that perhaps 
read would be cheaper so that I could lock operations down, without 
flushing caches and such.  But, now that I think longer and harder, I do 
know that the read must use synchronized() semantics, and that, in and 
of itself will create the side effects that are being discussed here.

private Object countLock = new Object();
private int count;
public int getCount() {
	synchronized( countLock ) {
		return count;
	}
}

public int addCount( int val ) {
	synchronized( countLock ) {
		count += val;
	}
}

is the same thing as doing

private Lock countLock = new ReentrantReadWriteLock();
private int count;
public int getCount() {
	Lock l = countLock.readLock();
	try {
		l.lock();
		return count;
	} finally {
		l.unlock();
	}
}

public int addCount( int val ) {
	Lock l = countLock.writeLock();
	try {
		l.lock();
		count += val;
	} finally {
		l.unlock();
	}
}

which, in and of itself doesn't look very exciting as a replacement. 
But, there are some more interesting opportunities for managing the 
state around the Locks with all of the associated methods on Lock as 
well as the expanded methods on these two types of Locks.

> Locks are intended as a direct alternative for use of synchronized
> blocks/methods. Hence the Lock interface specifies:

I guess I just didn't see this as the literal statement that it is 
intended to be.

> "All Lock implementations must enforce the same memory synchronization
> semantics as provided by the built-in monitor lock:
> 
> - A successful lock operation acts like a successful monitorEnter action
> - A successful unlock operation acts like a successful monitorExit action "

In my opinion, having this level of implementation detail in the 
documentation adds some complications because it doesn't tell the casual 
user anything.  Nothing in the language or API has those words in it. 
Only the underlying implementation details in JNI have such things.  I 
think this should say.

  - A successful lock operation is equivalent to beginning a 
synchronized section of code.

  - A successful unlock operation is equivalent to exiting the 
previously entered synchronized section of code.

This makes it clear that everything we depended on happening before 
still happens.

One might be tempted to add phrases like:

On lock entry, all Java Memory Model semantics for synchronized are met 
including...

But I think that just makes it even more likely that people will read 
stuff that is not important to them and become confused by their 
interpretation of the words and phrases therein.

> Has the confusion arisen by trying to figure out how this is actually
> achieved for a given Lock implementation? Or is the whole JMM so confusing
> that anything related to it causes confusion?

Certainly, I don't have any issues with understanding, now, what was 
intended.  The concepts of the JMM are complex, but not confusing to me. 
  The scary string of comments on that forum thread, to me, just go to 
show how many people still think that the Java language and the Java 
platform as implemented in the JVM are two completely separate things 
and that you have to look under the covers to know what will happen.

For me, the javadocs should always be enough for a method's description.

The problem here maybe related to the fact that this work took the 
semantics of a keyword and made those visible in an interface with 
program structure issues and documentation semantic issues that are 
apparently confusing.

> This aspect of things was meant to be a "no-brainer" - you shouldn't be
> worrying about the details. Some of the comments in that forum thread are
> scary! - people are delving into unneccessary detail far too much.

And I am one to ignore the JLS and JMM until I can't explain what I see. 
  Then I have to look at what is intended to be happening based on the 
specs.

Apparently I just completely missed the boat on understanding these 
changes.  I should have gone back and reread and thought about it first. 
  When I was composing that email I was thinking that the JMM equivalent 
synchronized flush would not be done implicitly by the lock() call. 
Otherwise it would have been called something else, besides lock(). If I 
would have thought a little longer and read the docs again, I wouldn't 
have volunteered such useless information...

Please just swat me up the side of the head and I'll go sit in the corner...

Gregg Wonderly


More information about the Concurrency-interest mailing list