valhalla-spec-comments post from jackammo77 at gmail.com requires approval
John Rose
john.r.rose at oracle.com
Wed Feb 20 00:20:55 UTC 2019
On Feb 19, 2019, at 2:46 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
>
> So what you're suggesting amounts to: inflate an interned proxy object and lock on that. Which is surely doable, but is no longer a "just use the box", since there is no box to "just" use.
Hey Brian I think you cleverly slipped in the word "interned",
which (all by itself) changed the commenter's suggestion from
one bad thing to a different bad thing.
The commenter Jack says "values (like an int) need to be boxed".
What happens under the covers of "boxing like an int" is
one of three things:
1. The boxing operation always returns the same Object reference,
as in the case Integer.valueOf(42) (or any other integer in the range
[-128.127]).
2. The boxing operation never returns the name Object reference,
as in the case new Integer(42) or (probably) Integer.valueOf(42000).
3. The boxing operation sometimes produces the same Object
reference more than once for the same input value, as in the
case new Integer(x) where x is something unpredictable like
new Random().nextInt(), or (more subtly) the boxing process
chooses between new Integer(x) and Integer.valueOf(x),
unpredictably.
Each of those three things is bad, in a somewhat different way.
The middle bad thing is bad, in that the synchronization will
optimize away to a no-op, since synchronizing on a unique
reference is guaranteed to do nothing. Why is that bad? It
means there is this expression in the code which (a) is expensive
and (b) looks impressive, and (c) surprises everyone by doing
nothing. Not a good thing to design into the core of the language.
The first bad thing is bad for two reasons: First, it provides
an endless source of unnamed but global variables, the monitor
states of all the proxy objects which are just sitting there
waiting to be locked. These days, side channels of all sorts
are frowned upon, and this is a side channel which adds
no value to the ecosystem. (I'd love to see it shut down.)
Second, this set of global variables would be extraordinarily
difficult to engineer (again, with no benefit except to builders
of sneaky side channels).
The third bad thing combines the badness of the other two,
with unpredictability added.
Brian, by inserting the term "intern" you shifted the focus
from 2 or 3 to 1. Probably because it is the least bad of
the bad things, given that it produces predictable (if silly
and expensive) behaviors. But the engineering costs of that
are the greatest, because it requires maintenance of an
intern table for each value type, complete with multi-weak
references for values containing reference fields. All
that, for no benefit except a crutch to bad code that locks
on random references? Not a very pretty prospect.
This is why "just make a proxy object", while easy to
suggest, is not likely to happen unless we somehow
realize that all the other options are even worse.
For me, I think we should all work on getting used to
the idea that some Java objects *should not* be
synchronizable. Well, that's already true, but let's
give our JVM permission to diagnose that particular
"should not" with an IllegalMonitorStateException
or something like that. Bad? Yes, but the least-bad,
where value types are concerned.
— John
More information about the valhalla-dev
mailing list