bottleneck by java.lang.Class.getAnnotations() - proposed patch (original) (raw)

Peter Levart peter.levart at gmail.com
Sun Nov 4 23:09:36 UTC 2012


Hi,

I propose the following patch to java.lang.Class in order to overcome the synchronization bottleneck when accessing annotations from multiple threads. The patch packs the 'annotations' and 'declaredAnnotations' Maps together with an int redefinedCount into a structure:

 static class Annotations {
     final Map<Class<? extends Annotation>, Annotation> annotations;
     final Map<Class<? extends Annotation>, Annotation> 

declaredAnnotations; final int redefinedCount;

which is referenced by a single volatile Class.annotations field. Instead of initAnnotationsIfNecessary() there's a getAnnotationsPrivate() method that uses simple double-checked locking to lazily initialize and return this structure. The slow-path part is still synchronized to ensure that Class.setAnnotationType/getAnnotationType call backs from AnnotationType are only done while holding a lock.

Regards, Peter

Here's the patch to jdk8 source:

diff -r 7ac292e57b5a src/share/classes/java/lang/Class.java --- a/src/share/classes/java/lang/Class.java Thu Nov 01 14:12:21 2012 -0700 +++ b/src/share/classes/java/lang/Class.java Sun Nov 04 23:53:04 2012 +0100 @@ -2237,10 +2237,8 @@ declaredFields = publicFields = declaredPublicFields = null; declaredMethods = publicMethods = declaredPublicMethods = null; declaredConstructors = publicConstructors = null;

@@ -3049,8 +3047,7 @@ if (annotationClass == null) throw new NullPointerException();

getAnnotationsPrivate().annotations.get(annotationClass); }

  /**

@@ -3070,40 +3067,52 @@ * @since 1.5 */ public Annotation[] getAnnotations() {

AnnotationParser.toArray(getAnnotationsPrivate().annotations); }

  /**
   * @since 1.5
   */
  public Annotation[] getDeclaredAnnotations()  {

AnnotationParser.toArray(getAnnotationsPrivate().declaredAnnotations); }

  // Annotations cache

annotations;

declaredAnnotations;

superClass.annotations.entrySet()) {

(AnnotationType.getInstance(annotationClass).isInherited())

AnnotationParser.parseAnnotations(

e : superClass.getAnnotationsPrivate().annotations.entrySet()) {

e.getKey();

(AnnotationType.getInstance(annotationClass).isInherited())

redefinedCount);

@@ -3119,6 +3128,18 @@ return annotationType; }

declaredAnnotations;

annotations, Map<Class<? extends Annotation>, Annotation> declaredAnnotations, int redefinedCount) {



More information about the core-libs-dev mailing list