[concurrency-interest] The Atomic*FieldUpdater situation

David M. Lloyd david.lloyd at redhat.com
Sun Jul 22 16:47:57 EDT 2012

On 07/20/2012 08:34 PM, David Holmes wrote:
> Hi Jason,
>> Jason T. Greene writes:
>> On 7/15/12 9:52 PM, David Holmes wrote:
>>> David M. Lloyd writes:
>>>> On 07/15/2012 09:35 PM, David Holmes wrote:
>>>>> David M. Lloyd writes:
>>>>>> On 07/15/2012 06:14 AM, David Holmes wrote:
>>>>>>> David M. Lloyd writes:
>>>>>>>> What is the purpose of the access-time access check in the
>>>>>>>> atomic field updater classes?
>>>>>>> Do you mean the ensureProtectedAccess check?
>>>>>>> This is to ensure that you can't get an updater for a protected
>>>>>>> inherited field in SubtypeA, then use that updater to
>>>>>>> access/modify the field in an instance of SubtypeB.
>>>>>> Which is ridiculous because if a subclass "inherited" access
>>>>>> to a normal
>>>>>> protected field on my class, I'd still be able to access it
>> directly in
>>>>>> the base class... because fields aren't actually inherited.
>>>>> I think you are missing the point. Consider this:
>>>>> class Base {
>>>>>      protected volatile int x;
>>>>> }
>>>>> final class Secure extends Base { ... }
>>>>> Instances of Secure are only supposed to be used through their
>>>> public API,
>>>>> as defined by Base and Secure. I hope you will agree that if I have an
>>>>> instance of Secure I shouldn't be able to arbitrarily mess with
>>>> the value of
>>>>> x?
>>>>> But given
>>>>> class BackDoor extends Base {
>>>>>       static AtomicIntegerFieldUpdater<Base>   u = ...
>> (Base.class, "x");
>>>>>       public static void setBaseX(Base target, int newX) {
>>>>>          u.set(target, newX);
>>>>>       }
>>>>> }
>>>>> without these protected access checks, BackDoor.setBaseX would
>>>> allow you to
>>>>> update _any_ instance of Base.
>>>> I see your point, but in this case, wouldn't it be better to restrict
>>>> updaters from being created on any class but their own, regardless of
>>>> the access of the field?  In other words, we'd allow:
>>>>       static AtomicIntegerFieldUpdater<BackDoor>  u = ...
>> (Backdoor.class,
>>>> "x");
>>>> but not:
>>>>       static AtomicIntegerFieldUpdater<Base>  u = ... (Base.class, "x");
>>>> from BackDoor.
>>> In hindsight, in the context of the current discussion, it may have been
>>> better to restrict things this way to allow access checks to be
>> elided. But
>>> that has to be weighed up against use-cases where it is an
>> inherited field that needs the atomic update.
>> I still don't get why this needs to operate any differently than
>> reflection. With reflection I can do the same thing in Backdoor. I just
>> make a call to setAccessible, and a security check is done with a
>> security manager. Why can't the updaters do the same?
> Because it is not reflection. Reflection is (in part) a mechanism to step
> outside the language to do things the language wouldn't normally permit. The
> atomic updaters are intended as an extension to normal field operations
> (putfield/getfield) and so they enforce language level access controls.

That is sort of baloney logic.  The atomic updaters are intended as a 
way to implement atomic operations, which are used when performance is a 
priority.  Trying to make it smell like a language feature is very 
misguided IMO; it is far more consistent with the language *and* the 
purpose of the class if the protection of the object itself was used for 
the purpose of protecting the field.

You don't have to give things extra runtime behavior in the name of 
being able to "step outside of the language".  I think it takes a fairly 
imaginative interpretation of the JLS to arrive at the conclusion that 
object classes which act like language features must act in the exact 
same way as the language.  The language doesn't include atomic field 
accesses; does this then mean that by this logic, specifying classes 
which do include this functionality should be disallowed?

If you really want extensions to normal field operations that act just 
like the language then they have to be in the language - otherwise that 
card just isn't playable.  It doesn't add anything useful to the 
specification; on the contrary it adds unreasonable and useless 
constraints.  If adding this functionality to the language *isn't* an 
option, then it makes far more sense to conform idiomatically to the 
mechanism that *is* available, which is an accessor object, which the 
user should be allowed to use as they set fit.


More information about the Concurrency-interest mailing list