From: Lew on
Lew wrote:
> How is 42 any better than 0? And what, may I ask, is wrong with 0?

I meant to say what's wrong with 17?

Andreas Leitgeb wrote:
>> Has anyone found e.g. an english [sic] dictionary-word with hashCode
>> 0, yet?
>> Or perhaps the name of some commonly used class in Java standard library
>> or some other String likely occurring in innocent code?

Lew wrote:
> ""

--
Lew
From: Lew on
Lew writes:
>> No. It isn't classes that are immutable, it's instances. We say

Jukka Lahtinen wrote:
> Uhh.. but the class is what defines its instances and where the
> immutability is implemented (or mutability not implemented).
> Looks like you missed the point in my question.
> So let me rephrase:
> If class A is annotated with @Immutable and we define a class B that
> extends A, would the instances of class B have to be immutable?
> (Or does @Immutable require class A to be final?)

Immutability can only apply to the parent class because it only promises that
instances of 'A' itself are immutable. It cannot reach out into subclasses,
most or all of which are inaccessible to any kind of checker. Immutability of
'A' can only pertain to the state visible or 'A' instances.

Of course if you add mutable state in a way not visible to '@Immutable' you'll
break the promise. This is not dissimilar to the way you break the contract
of 'equals()' in a subtype that adds more relevant state, if the parent
implementation is allowed to compare to subtypes.

Making 'A' final is a way to guarantee that all instances declared as type 'A'
are immutable.

>>> If so, and Object were immutable, then EVERY class should be immutable.

'Object' is not immutable since it doesn't have state. It's also not mutable.

--
Lew



--
Lew
From: Mike Schilling on


"Lew" <noone(a)lewscanon.com> wrote in message
news:i1v5fv$h9p$1(a)news.albasani.net...
> Tom Anderson wrote:
>>> The beauty of the String approach, of using a special value of code to
>>> indicate that it had not been calculated, is that you don't need any
>>> synchronisation for safety, just the JLS's guarantee of no word tearing
>>> in writes and reads of int variables. Because it combines the flag and
>>> value fields in a single int, they are read and written atomically as a
>>> pair. Of course, were you to do this, you might want to avoid String's
>>> ability to generate a code which looks like a flag indicating the lack
>>> of a code (ie 0). But then, you might think the one in four billion
>>> chance of it happening was insignificant.
>
> Joshua Cranmer wrote:
>> Or you could store the value in the low word of a long and the flag in
>> the upper word.
>
> But then you'd need to synchronize, unlike in 'String#hashCode()'.

Or you could define the hashCode() value for a String whose calculated value
is 0 as 1.

From: Peter Duniho on
Jim Janney wrote:
> [...]
> Instances of SannyCode are immutable, in the context of a single
> threaded application, but they are not thread-safe.

Right. As Andreas points out, you've simply replicated the mistake I
described as a potential problem had the String.hashCode() method been
implemented correctly.

Unfortunately, I made my statement poorly. Even the java.lang.String
example points to how an immutable type _could_ be thread-unsafe (in the
way that I already described). So it should have been clear that I
wasn't trying to say that lazily-computed values in an immutable class
are _inherently_ thread safe. You still have to implement the
computation correctly.

The point I was trying to make is that done correctly, immutable _does_
imply thread-safe, just as the JCIP page says. And I don't think it's
necessary to read their statement as claiming that any immutable
implementation is inherently thread-safe. Rather, I believe that they
are describe the _rules_ for the annotations. Don't mark a type as
"@Immutable" unless you can also mark it as "@ThreadSafe".

Pete
From: Andreas Leitgeb on
Lew <noone(a)lewscanon.com> wrote:
> Tom Anderson wrote:
>>> To make this method safe, you either have to synchronize the whole thing,
>>> or do the update of calculated and code atomically at the end.
> Andreas Leitgeb wrote:
>> I'd have expected that if "calculated" was assigned *after* "code", that
>> would suffice without further synchronisation or volatile-ity of the fields.
>> Am I still too naive?
> Yes. Don't omit what tom said about /happens-before/:
>> In fact, it's worse than that. Thread A could finish the method and update
>> both calculated and code, but because there is no happens-before relationship
>> between thread A and thread B, it's possible that B could come along later,
>> and see the updated calculated but *not* the updated code. So even without
>> an unlucky timeslice end, there is no guarantee of safety here.

There is still a misunderstanding - I'm just not sure if it's on my or your
side.
Thread 1 assigns two plain word-sized fields: a and then b.
can Thread 2 happen to see b's new value, and (after that) a's old value?

Tom's explanation was (as far as I understood it) based on the code-sample
where the flag was set before the code, and he rightly pointed out that this
gap may be even much longer than expected. Can it reverse, as well?

> Andreas Leitgeb wrote:
>> I guess, I'd have spent one "if (h==0) { h=42; }" just before "hash = h;"
>> After the calculation loop, that extra "if" really wouldn't have hurt.
> How is 42 any better than 0? And what, may I ask, is wrong with [17]?

The disadvantage for (non-trivial) strings with a 0 hashCode has already
been discussed. A disadvantage that hits only a very small fraction of all
strings, but it may hit that fraction possibly noticeably.
For 42: I didn't claim it to be any technically special number - just that
I'd have picked it - Googling for 42 will likely show a possible reason for
that choice)

>> Has anyone found e.g. an english [sic] dictionary-word with hashCode 0, yet?
>> Or perhaps the name of some commonly used class in Java standard library
>> or some other String likely occurring in innocent code?
> ""

Damn, I shouldn't have trimmed the "non-trivial" that I had already written.
At least, the hashCode for "" is quite efficiently obtained.