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