From: Peter Duniho on
Alan Gutierrez wrote:
> [...]
>> If you like, we can just copy/paste the back-and-forth we had there to
>> this newsgroup.
>
> I'd be interested to see that. I'd tend to agree with Arne. I generally
> avoid holding the monitor on an object whose class is not part of the
> code base, that is, I know that there is a monitor on every object, so I
> don't try to hold the monitor on an instance someone else's class,
> because that there for them to use.
>
> The encapsulation as proscribed by the C# "best-practice" makes it
> impossible, I understand, but I really cotton to Arne's comment on
> "best-practices".

The C# "best-practice" recommendation is to not lock on "this".
Following that recommendation in no way prevents _other_ code from
locking on the object reference itself.

In fact, there is no way to prevent other code from locking on the
object reference itself, short of acquiring that lock and never
releasing it. Hence the recommendation for a class to not lock on its
own "this" reference. There's no way to know what other code might be
using that reference for a lock.

> So, other than the ounce of prevention, what makes Arne wrong? (Or, link
> to the previous discussion if you're not interested.)

Here's the link:
http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/95fa9dbd85a37227/dd03736b7038541c

As far as my point of view goes, I find the advice useful for the same
reason I find the general OOP philosophy of information hiding and
encapsulation useful. There are a number of mistakes I have
successfully avoided even before I was using OOP languages and which are
prevented or at least minimized through the use of good OOP practices.
But the fact that I've never actually had or seen those problems doesn't
mean I should eschew OOP best-practices.

Should I insist that I make and/or observe every possible mistake
possible before I incorporate policies in my own code to avoid those
mistakes?

You may find these discussions interesting as well:
http://stackoverflow.com/questions/442564/avoid-synchronizedthis-in-java
http://www.yoda.arachsys.com/csharp/threads/lockchoice.shtml

The former is not in any way 100% pro-"don't lock on this", but it has a
bit of reasonable back-and-forth. It also includes a (perhaps
contrived) code example of how using "this" for synchronization not only
can lead to problems, it can expose code to an intentional
denial-of-service attack (not necessarily something that is even
possible in all scenarios, but certainly worth thinking about IMHO).

Pete
From: Alan Gutierrez on
Peter Duniho wrote:
> Alan Gutierrez wrote:
>> [...]
>>> If you like, we can just copy/paste the back-and-forth we had there
>>> to this newsgroup.
>>
>> I'd be interested to see that. I'd tend to agree with Arne. I
>> generally avoid holding the monitor on an object whose class is not
>> part of the code base, that is, I know that there is a monitor on
>> every object, so I don't try to hold the monitor on an instance
>> someone else's class, because that there for them to use.
>>
>> The encapsulation as proscribed by the C# "best-practice" makes it
>> impossible, I understand, but I really cotton to Arne's comment on
>> "best-practices".
>
> The C# "best-practice" recommendation is to not lock on "this".
> Following that recommendation in no way prevents _other_ code from
> locking on the object reference itself.
>
> In fact, there is no way to prevent other code from locking on the
> object reference itself, short of acquiring that lock and never
> releasing it. Hence the recommendation for a class to not lock on its
> own "this" reference. There's no way to know what other code might be
> using that reference for a lock.
>
>> So, other than the ounce of prevention, what makes Arne wrong? (Or,
>> link to the previous discussion if you're not interested.)
>
> Here's the link:
> http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/95fa9dbd85a37227/dd03736b7038541c
>
>
> As far as my point of view goes, I find the advice useful for the same
> reason I find the general OOP philosophy of information hiding and
> encapsulation useful. There are a number of mistakes I have
> successfully avoided even before I was using OOP languages and which are
> prevented or at least minimized through the use of good OOP practices.
> But the fact that I've never actually had or seen those problems doesn't
> mean I should eschew OOP best-practices.

Thank you for taking the time to layout a lesson plan. I read it all.

Yes, it is truly an ounce of prevention, and an appropriate application
of encapsulation. Somewhere else in this list, someone wrote, objects
are cheap, defects are expensive. Create a mutex Object makes sense.

The Collections.concurrentMap implementation is probably considered by
C# programmers to be too clever.

--
Alan Gutierrez - alan(a)blogometer.com - http://twitter.com/bigeasy
From: Lew on
markspace wrote:
> I agree that the only practical way to pass an object to the EDT
> involves a shared lock. However, invokeLater() makes no such guarantee,

Are you kidding? The whole documented point of 'invokeLater()' and
'invokeAndWait()' is to push things to the EDT in a thread-safe manner.

> and they'd be within their rights to change their implementation of
> invokeLater() and remove any shared locks, thus removing any
> synchronization and any happens-before semantics. Contrast this with the

They totally would not be within their rights to do that, as it would violate
the entire point of the method. When you look at the source and see all the
work they did to build synchronization into those methods, you will understand
that it's there for a reason - to do what the methods freaking promise to do!

> docs of some of the concurrent classes like Executor, which does provide
> an explicit memory consistency guarantee.

I agree that the promise should be repeated in the Javadocs for the methods
themselves, but I'm not going to bet that anyone's going to remove
synchronization from the implementation of the 'invoke...()' methods.

--
Lew
From: markspace on
Lew wrote:

> I agree that the promise should be repeated in the Javadocs for the
> methods themselves,

This is my main point. If that is indeed their intention, they should
document it. The Swing team needs a once-over with a wet noodle for
some of their concurrency documentation.
From: markspace on
Lew wrote:

> markspace wrote:
>> I agree that the only practical way to pass an object to the EDT
>> involves a shared lock. However, invokeLater() makes no such guarantee,
>
> Are you kidding? The whole documented point of 'invokeLater()' and
> 'invokeAndWait()' is to push things to the EDT in a thread-safe manner.


Addendum: no, I'm not kidding. Where do you see it documented that the
purpose of invokeLater() is to "push things" to the EDT? I only see it
documented that invokeLater() executes code, so that already existing
objects, created on the EDT, can be accessed in a thread safe manner.

All the examples of using invokeLater() I can find carefully avoid any
access of objects created off the EDT, unless that object is made thread
safe some other way (e.g., use of final keyword).

If you can show documentation that even partially supports your claim,
I'd love to see it.