< prev index next >

src/java.base/share/classes/java/lang/reflect/Executable.java

Print this page
rev 11212 : 8068736: Avoid synchronization on Executable/Field.declaredAnnotations
Reviewed-by: jfranck

@@ -586,26 +586,33 @@
      */
     public Annotation[] getDeclaredAnnotations()  {
         return AnnotationParser.toArray(declaredAnnotations());
     }
 
-    private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
+    private transient volatile Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
 
-    private synchronized  Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
-        if (declaredAnnotations == null) {
+    private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
+        Map<Class<? extends Annotation>, Annotation> declAnnos;
+        if ((declAnnos = declaredAnnotations) == null) {
+            synchronized (this) {
+                if ((declAnnos = declaredAnnotations) == null) {
             Executable root = getRoot();
             if (root != null) {
-                declaredAnnotations = root.declaredAnnotations();
+                        declAnnos = root.declaredAnnotations();
             } else {
-                declaredAnnotations = AnnotationParser.parseAnnotations(
+                        declAnnos = AnnotationParser.parseAnnotations(
                     getAnnotationBytes(),
                     sun.misc.SharedSecrets.getJavaLangAccess().
                     getConstantPool(getDeclaringClass()),
-                    getDeclaringClass());
+                                getDeclaringClass()
+                        );
             }
+                    declaredAnnotations = declAnnos;
         }
-        return declaredAnnotations;
+            }
+        }
+        return declAnnos;
     }
 
     /**
      * Returns an {@code AnnotatedType} object that represents the use of a type to
      * specify the return type of the method/constructor represented by this
< prev index next >