You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2019/12/25 10:53:49 UTC

[groovy] branch master updated: Make lazy nodes initialized only once even if accessed by multi-threads

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new d4caa1e  Make lazy nodes initialized only once even if accessed by multi-threads
d4caa1e is described below

commit d4caa1edf1fdaa2f3bc1812476e9851ac9a2f31b
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Dec 25 18:49:51 2019 +0800

    Make lazy nodes initialized only once even if accessed by multi-threads
---
 .../groovy/ast/decompiled/LazyConstructorNode.java | 16 ++++++++++++----
 .../groovy/ast/decompiled/LazyFieldNode.java       | 22 +++++++++++++++-------
 .../groovy/ast/decompiled/LazyMethodNode.java      | 18 +++++++++++++-----
 3 files changed, 40 insertions(+), 16 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyConstructorNode.java b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyConstructorNode.java
index 50bef15..b2e0eed 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyConstructorNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyConstructorNode.java
@@ -45,16 +45,24 @@ class LazyConstructorNode extends ConstructorNode {
     private final Supplier<ConstructorNode> constructorNodeSupplier;
     private ConstructorNode delegate;
 
+    private volatile boolean initialized;
+
     public LazyConstructorNode(Supplier<ConstructorNode> constructorNodeSupplier) {
         this.constructorNodeSupplier = constructorNodeSupplier;
     }
 
     private void init() {
-        if (null != delegate) return;
-        delegate = constructorNodeSupplier.get();
+        if (initialized) return;
+
+        synchronized (this) {
+            if (initialized) return;
+            delegate = constructorNodeSupplier.get();
+
+            ClassNode declaringClass = super.getDeclaringClass();
+            if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
 
-        ClassNode declaringClass = super.getDeclaringClass();
-        if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
+            initialized = true;
+        }
     }
 
     @Override
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyFieldNode.java b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyFieldNode.java
index 94d2ed5..1b513be 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyFieldNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyFieldNode.java
@@ -42,7 +42,9 @@ class LazyFieldNode extends FieldNode {
     private final Supplier<FieldNode> fieldNodeSupplier;
     private FieldNode delegate;
 
-    private String name;
+    private final String name;
+
+    private volatile boolean initialized;
 
     public LazyFieldNode(Supplier<FieldNode> fieldNodeSupplier, String name) {
         this.fieldNodeSupplier = fieldNodeSupplier;
@@ -50,14 +52,20 @@ class LazyFieldNode extends FieldNode {
     }
 
     private void init() {
-        if (null != delegate) return;
-        delegate = fieldNodeSupplier.get();
+        if (initialized) return;
+
+        synchronized (this) {
+            if (initialized) return;
+            delegate = fieldNodeSupplier.get();
+
+            ClassNode declaringClass = super.getDeclaringClass();
+            if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
 
-        ClassNode declaringClass = super.getDeclaringClass();
-        if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
+            ClassNode owner = super.getOwner();
+            if (null != owner) delegate.setOwner(owner);
 
-        ClassNode owner = super.getOwner();
-        if (null != owner) delegate.setOwner(owner);
+            initialized = true;
+        }
     }
 
     @Override
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyMethodNode.java b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyMethodNode.java
index 11f12da..dc8494d 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/LazyMethodNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/LazyMethodNode.java
@@ -45,7 +45,9 @@ class LazyMethodNode extends MethodNode {
     private final Supplier<MethodNode> methodNodeSupplier;
     private MethodNode delegate;
 
-    private String name;
+    private final String name;
+
+    private volatile boolean initialized;
 
     public LazyMethodNode(Supplier<MethodNode> methodNodeSupplier, String name) {
         this.methodNodeSupplier = methodNodeSupplier;
@@ -53,11 +55,17 @@ class LazyMethodNode extends MethodNode {
     }
 
     private void init() {
-        if (null != delegate) return;
-        delegate = methodNodeSupplier.get();
+        if (initialized) return;
+
+        synchronized (this) {
+            if (initialized) return;
+            delegate = methodNodeSupplier.get();
+
+            ClassNode declaringClass = super.getDeclaringClass();
+            if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
 
-        ClassNode declaringClass = super.getDeclaringClass();
-        if (null != declaringClass) delegate.setDeclaringClass(declaringClass);
+            initialized = true;
+        }
     }
 
     @Override