Proposal: Fully Concurrent ClassLoading

David Holmes david.holmes at
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.


> On Tue, Dec 11, 2012 at 7:40 PM, David Holmes<david.holmes at>  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