Skip to content

Commit adc4462

Browse files
committed
SLING-12519 - Use AtomicReference in ScriptableBase.java for lazy initialization of NativeJavaObject
* Use AtomicReference for thread-safe lazy initialization of NativeJavaObject. * Introduce a special NULL_OBJECT placeholder as an intermediate state to avoid repeated construction of NativeJavaObject in each compareAndSet(...) operation.
1 parent c4fac55 commit adc4462

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.lang.reflect.Method;
2222
import java.util.HashSet;
2323
import java.util.Set;
24+
import java.util.concurrent.atomic.AtomicReference;
2425

2526
import org.mozilla.javascript.NativeJavaObject;
2627
import org.mozilla.javascript.Scriptable;
@@ -31,12 +32,13 @@
3132
*/
3233
public abstract class ScriptableBase extends ScriptableObject {
3334

34-
private NativeJavaObject njo;
35+
private static final NativeJavaObject NULL_OBJECT = new NativeJavaObject();
36+
private final AtomicReference<NativeJavaObject> atomicNjoReference = new AtomicReference<NativeJavaObject>(null);
3537
private final Set<String> jsMethods = getJsMethodNames();
3638

3739
public static final String JSFUNC_PREFIX = "jsFunction_";
3840

39-
protected synchronized Object getNative(String name, Scriptable start) {
41+
protected Object getNative(String name, Scriptable start) {
4042
final Object wrapped = getWrappedObject();
4143

4244
if (wrapped == null) {
@@ -47,11 +49,11 @@ protected synchronized Object getNative(String name, Scriptable start) {
4749
return Scriptable.NOT_FOUND;
4850
}
4951

50-
if (njo == null) {
51-
njo = new NativeJavaObject(start, wrapped, getStaticType());
52+
// Use a NULL_OBJECT refernece to ensure only one initiation the real NatvieJavaObject.
53+
if (atomicNjoReference.compareAndSet(null, NULL_OBJECT)) {
54+
atomicNjoReference.compareAndSet(NULL_OBJECT, new NativeJavaObject(start, wrapped, getStaticType()));
5255
}
53-
54-
return njo.get(name, start);
56+
return atomicNjoReference.get().get(name, start);
5557
}
5658

5759
/** @return the Java object that we're wrapping, used to create a NativeJavaObject

0 commit comments

Comments
 (0)