From: markspace on
Peter Duniho wrote:

> If what you say were true, then you could not even count on the Runnable
> instance that you created to be valid during the invoked execution,
> since that's something that happened before the call to invokeLater(),
> but which wasn't synchronized. The "temp" field itself would be safe,


Correct. The Runnable here is not inherently thread safe, hence the
need for the volatile keyword.


> but nothing else in the Runnable instance would be (including, for
> example, a v-table as might be used to dispatch the call to run()).


There's nothing in the JLS that describes a need to make *methods* safe
for concurrency, or for the programmer to worry about internal
structures such as a hypothetical v-table. The JVM is guaranteed to
construct a class correctly. The fields used by the programmer must be
made thread safe somehow by the programmer.

Right now you are just makin' stuff up.


Weird side note: I was just reading through the JLS to make sure I had
a couple of things right. You know what else is guaranteed to be
visible and thread safe? Objects referred to by final fields, up to the
point where said objects are assigned to the final field. Thus this
works as good as a volatile:

public class Main {
public static void main( String... args ) {
final MyClass test = new MyClass();
SwingUtilities.invokeLater( new Runnable() {
private final MyClass model = test;
public void run() {
... // ok to use model now...
}
} );
}
}
From: Peter Duniho on
markspace wrote:
> Peter Duniho wrote:
>
>> If what you say were true, then you could not even count on the
>> Runnable instance that you created to be valid during the invoked
>> execution, since that's something that happened before the call to
>> invokeLater(), but which wasn't synchronized. The "temp" field itself
>> would be safe,
>
> Correct. The Runnable here is not inherently thread safe, hence the
> need for the volatile keyword.

It is quite common to pass a Runnable to invoke�() without any use of
"volatile" or other synchronization in the implementation.

None of those examples would be correct if your assertion was.

>> but nothing else in the Runnable instance would be (including, for
>> example, a v-table as might be used to dispatch the call to run()).
>
> There's nothing in the JLS that describes a need to make *methods* safe
> for concurrency, or for the programmer to worry about internal
> structures such as a hypothetical v-table. The JVM is guaranteed to
> construct a class correctly. The fields used by the programmer must be
> made thread safe somehow by the programmer.
>
> Right now you are just makin' stuff up.

I'm simply pointing out that there are implicit order-of-operation
guarantees that necessarily come along with something like the invoke�()
methods that, without such guarantees, would break all sorts of code,
including that implicitly executed.

I'm only "makin' stuff up" inasmuch as I haven't bothered to read the
JLS for the purpose of this discussion. But I don't need to.

It's patently obvious that the invoke�() methods couldn't possibly be
useful unless they included synchronization between the thread that
calls them and the thread where the Runnable is actually invoked. The
only way to safely get the Runnable reference from one thread to the
other is for there to be some synchronization, and such synchronization
will necessarily take care of ensuring everything up to the invoke�()
call is seen in the other thread after the invoke�() call.

I did mention other aspects of initialization in my discussion, but you
seem to be getting too distracted by the specifics of those comments,
and I now regret introducing those comments. I should have simply
omitted them, because they aren't really needed in order to understand
why invoke�() must have synchronization. The EDT can't even reliably
get the reference to the invoked Runnable unless there's some
synchronization.

Pete
From: John B. Matthews on
In article <i22ll3$hdt$1(a)news.eternal-september.org>,
markspace <nospam(a)nowhere.com> wrote:

> Weird side note: I was just reading through the JLS to make sure I
> had a couple of things right. You know what else is guaranteed to be
> visible and thread safe? Objects referred to by final fields, up to
> the point where said objects are assigned to the final field. Thus
> this works as good as a volatile:
>
> public class Main {
> public static void main( String... args ) {
> final MyClass test = new MyClass();
> SwingUtilities.invokeLater( new Runnable() {
> private final MyClass model = test;
> public void run() {
> ... // ok to use model now...
> }
> } );
> }
> }

IIUC, this is foundational to the lazy initialization holder
class idiom [1], also known as the initialize-on-demand holder class
idiom [2].

[1] Joshua Bloch, Effective Java, second edition, item 71.
[2]<http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom>

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>
From: Lew on
markspace wrote:
>> Weird side note: I was just reading through the JLS to make sure I
>> had a couple of things right. You know what else is guaranteed to be
>> visible and thread safe? Objects referred to by final fields, up to
>> the point where said objects are assigned to the final field. Thus
>> this works as good as a volatile:
>>
>> public class Main {
>> public static void main( String... args ) {
>> final MyClass test = new MyClass();
>> SwingUtilities.invokeLater( new Runnable() {
>> private final MyClass model = test;
>> public void run() {
>> ... // ok to use model now...

Or you could use 'test' directly.

>> }
>> } );
>> }
>> }

John B. Matthews wrote:
> IIUC, this is foundational to the lazy initialization holder
> class idiom [1], also known as the initialize-on-demand holder class
> idiom [2].
>
> [1] Joshua Bloch, Effective Java, second edition, item 71.
> [2]<http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom>

Actually what's foundational to that is not so much final variables as final
static fields.

--
Lew
From: Arne Vajhøj on
On 19-07-2010 14:51, Peter Duniho wrote:
> The first mechanism has to do with semantics surrounding object
> construction. In .NET, the specification ensures that whatever happens
> in the constructor "happens before" any other code that uses the
> reference after the constructor completes (.NET doesn't actually use the
> term "happens-before", but it's the same idea). I would expect Java to
> be the same in this respect.

Where does it say that?

The only thing I can find seems to say the exact opposite:

<quote>
It is explicitly not a requirement that a conforming implementation of
the CLI guarantee that all state updates
performed within a constructor be uniformly visible before the
constructor completes.
</quote>

Arne