Proposal: Fully Concurrent ClassLoading
David Holmes
david.holmes at oracle.com
Wed Dec 12 23:48:46 UTC 2012
On 13/12/2012 1:51 AM, Zhong Yu wrote:
> If a class loader is declared fully concurrent, yet
> getClassLoadingLock() is invoked, what's the harm of returning a
> dedicated lock anyway, exactly like what's done before?
The whole point is to get rid of the lockMap and these lock objects.
I could return a sentinel Object in all cases rather than null but that
just seems to encourage continued use of something that shouldn't be
used with a fully concurrent loader.
Returning null versus throwing an exception is mostly a matter of style.
I'd want to hear from anyone who invokes getClassLoadingLock() on any of
the system classloaders to see which is preferable.
Thanks for the comments.
David
> On Tue, Dec 11, 2012 at 7:40 PM, David Holmes<david.holmes at oracle.com> wrote:
>> On 11/12/2012 9:58 PM, Peter Levart wrote:
>>>
>>> On 12/11/2012 12:27 PM, David Holmes wrote:
>>>>
>>>> Peter,
>>>>
>>>> You are convincing me that all superclasses must be fully concurrent
>>>> too. Otherwise we are just trying to second-guess a whole bunch of
>>>> what-ifs. :)
>>>
>>>
>>> If you think some more, yes. The superclass might not use
>>> getClassLoadingLock() but rely on the fact that findClass() is allways
>>> called under a guard of per-class-name lock, for example. It's a matter
>>> of how far to go to prevent such miss-behaving fully-concurrent
>>> subclasses. So far to also prevent fully-concurrent subclasses that
>>> would otherwise be perfectly correct?
>>>
>>> Maybe not. Creating custom ClassLoaders is not an average programmer's
>>> job. Those that do this things will of course study the implementations
>>> of superclasses they extend and do the right thing. And it's reasonable
>>> to expect that they more or less will only extend JDK's ClassLoaders -
>>> but on the other hand if they only extend JDK's class loaders, they are
>>> not prevented to be fully-concurrent either way. Hm...
>>
>>
>> Again I think it is just too hard to try and second-guess how a
>> parallel-loader might rely on the per-class locks (I actually don't see any
>> reasonable use for them beyond flow-control), and then how a concurrent
>> loader subclass might need to modify things.
>>
>> If we simply disallow this then we can relax that constraint in the future
>> if valid use-cases turn up for that capability. Of course if someone has a
>> valid use-case during this discussion phase then of course that will
>> influence the decision.
>>
>> Thanks,
>> David
>>
>>> Peter
>>>
>>>>
>>>> Thanks,
>>>> David
>>>>
>>>> On 11/12/2012 7:44 PM, Peter Levart wrote:
>>>>>
>>>>> On 12/11/2012 10:29 AM, David Holmes wrote:
>>>>>>
>>>>>> On 11/12/2012 7:20 PM, Peter Levart wrote:
>>>>>>>
>>>>>>> On 12/11/2012 03:55 AM, David Holmes wrote:
>>>>>>>>>
>>>>>>>>> Question on the source code: registerAsFullyConcurrent has confusing
>>>>>>>>> comment -
>>>>>>>>> do the super classes all need to be parallel capable? Or do the
>>>>>>>>> super
>>>>>>>>> classes all need
>>>>>>>>> to be FullyConcurrent? I assume the latter, so just fix the
>>>>>>>>> comments.
>>>>>>>>
>>>>>>>>
>>>>>>>> Actually it is the former. There's no reason to require that all
>>>>>>>> superclasses be fully-concurrent. Of course a given loaders degree of
>>>>>>>> concurrency may be constrained by what it's supertype allows, but
>>>>>>>> there's no reason to actually force all the supertypes to be
>>>>>>>> fully-concurrent: it is enough that they are at least all parallel
>>>>>>>> capable.
>>>>>>>
>>>>>>>
>>>>>>> Hi David,
>>>>>>>
>>>>>>> There is one caveat: if ClassLoader X declares that it is
>>>>>>> fully-concurrent and it's superclass Y is only parallel-capable,
>>>>>>> then X
>>>>>>> will act as fully-concurrent (returning null from
>>>>>>> getClassLoadingLock()). superclass Y might or might not be coded to
>>>>>>> use
>>>>>>> the getClassLoadingLock(). X therefore has to know how Y is coded.
>>>>>>> To be
>>>>>>> defensive, X could ask for Y's registration and declare itself as only
>>>>>>> parallel-capable if Y declares the same so that when Y is upgraded
>>>>>>> to be
>>>>>>> fully-concurrent, X would become fully-concurrent automatically. To
>>>>>>> support situations where the same version of X would work in two
>>>>>>> environments where in one Y is only parallel-capable and in the
>>>>>>> other Y
>>>>>>> is fully-concurrent, there could be a static API to retrieve the
>>>>>>> registrations of superclasses.
>>>>>>
>>>>>>
>>>>>> I don't quite follow this. What code in the superclass are you
>>>>>> anticipating that the subclass will use which relies on the lock? Or
>>>>>> is this just an abstract "what if" scenario?
>>>>>
>>>>>
>>>>> This is more or less "what if". There might be a subclass Y of say
>>>>> java.lang.ClassLoader that overrides loadClass or findClass, declares
>>>>> that it is parallel-capable and in the implementation of it's loadClass
>>>>> or findClass, uses getClassLoadingLock() to synchronize access to it's
>>>>> internal state. Now there comes class X extends Y that declares that it
>>>>> is fully-concurrent. Of course this will not work, X has to declare that
>>>>> it is parallel-capable, because Y uses getClassLoadingLock().
>>>>>
>>>>> What I suggested in the next message is to not change the registration
>>>>> API but rather provide getClassLoadingLock() that returns non-null locks
>>>>> when any of the superclasses declare that they are only
>>>>> parallel-capable, not fully-concurrent.
>>>>>
>>>>> Regards, Peter
>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> David
>>>>>> -----
>>>>>>
>>>>>>> Or, to have less impact on future deprecation of old parallel-capable
>>>>>>> registration API, the fully-concurrent registration API:
>>>>>>>
>>>>>>> protected static boolean registerAsFullyConcurrent()
>>>>>>>
>>>>>>> might take a boolean parameter:
>>>>>>>
>>>>>>> protected static boolean registerAsFullyConcurrent(boolean
>>>>>>> downgradeToPrallelCapableIfAnySuperclassIsNotFullyConcurrent)
>>>>>>>
>>>>>>>
>>>>>>> and provide no accessible API to find out what the registration
>>>>>>> actually
>>>>>>> did (register as parallel-capable or fully-concurrent - return true in
>>>>>>> any case).
>>>>>>>
>>>>>>> Since all JDK provided ClassLoaders will be made fully concurrent,
>>>>>>> this
>>>>>>> might only be relevant if there is vendor A that currently provides
>>>>>>> only
>>>>>>> parallel-capable ClassLoader implementation and there is vendor B that
>>>>>>> subclasses A's loader and wants to upgrade and be backward
>>>>>>> compatible at
>>>>>>> the same time.
>>>>>>>
>>>>>>> Does this complicate things to much for no real benefit?
>>>>>>>
>>>>>>> Regards, Peter
>>>>>>>
>>>>>
>>>
>>
More information about the core-libs-dev
mailing list