8068736: Avoid synchronization on Executable/Field.declaredAnnotations
authorredestad
Fri, 16 Jan 2015 12:41:36 +0100
changeset 28431 a5c817e7ddb5
parent 28430 a4f35c6aa3cc
child 28432 0b4c78ff36f3
8068736: Avoid synchronization on Executable/Field.declaredAnnotations Reviewed-by: jfranck, psandoz
jdk/src/java.base/share/classes/java/lang/reflect/Executable.java
jdk/src/java.base/share/classes/java/lang/reflect/Field.java
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java	Thu Jan 15 16:45:02 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java	Fri Jan 16 12:41:36 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -588,22 +588,29 @@
         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) {
-            Executable root = getRoot();
-            if (root != null) {
-                declaredAnnotations = root.declaredAnnotations();
-            } else {
-                declaredAnnotations = AnnotationParser.parseAnnotations(
-                    getAnnotationBytes(),
-                    sun.misc.SharedSecrets.getJavaLangAccess().
-                    getConstantPool(getDeclaringClass()),
-                    getDeclaringClass());
+    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) {
+                        declAnnos = root.declaredAnnotations();
+                    } else {
+                        declAnnos = AnnotationParser.parseAnnotations(
+                                getAnnotationBytes(),
+                                sun.misc.SharedSecrets.getJavaLangAccess().
+                                        getConstantPool(getDeclaringClass()),
+                                getDeclaringClass()
+                        );
+                    }
+                    declaredAnnotations = declAnnos;
+                }
             }
         }
-        return declaredAnnotations;
+        return declAnnos;
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java	Thu Jan 15 16:45:02 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java	Fri Jan 16 12:41:36 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1139,21 +1139,28 @@
         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) {
-            Field root = this.root;
-            if (root != null) {
-                declaredAnnotations = root.declaredAnnotations();
-            } else {
-                declaredAnnotations = AnnotationParser.parseAnnotations(
-                        annotations,
-                        sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()),
-                        getDeclaringClass());
+    private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
+        Map<Class<? extends Annotation>, Annotation> declAnnos;
+        if ((declAnnos = declaredAnnotations) == null) {
+            synchronized (this) {
+                if ((declAnnos = declaredAnnotations) == null) {
+                    Field root = this.root;
+                    if (root != null) {
+                        declAnnos = root.declaredAnnotations();
+                    } else {
+                        declAnnos = AnnotationParser.parseAnnotations(
+                                annotations,
+                                sun.misc.SharedSecrets.getJavaLangAccess()
+                                        .getConstantPool(getDeclaringClass()),
+                                getDeclaringClass());
+                    }
+                    declaredAnnotations = declAnnos;
+                }
             }
         }
-        return declaredAnnotations;
+        return declAnnos;
     }
 
     private native byte[] getTypeAnnotationBytes0();