diff --git a/base/src/main/java/org/eclipse/serializer/concurrency/LockScope.java b/base/src/main/java/org/eclipse/serializer/concurrency/LockScope.java index 4905164..033ac6f 100644 --- a/base/src/main/java/org/eclipse/serializer/concurrency/LockScope.java +++ b/base/src/main/java/org/eclipse/serializer/concurrency/LockScope.java @@ -24,13 +24,37 @@ */ public abstract class LockScope { - private final transient LockedExecutor executor = LockedExecutor.New(); + private transient volatile LockedExecutor executor; protected LockScope() { super(); } + /** + * Lazy initializes the executor. + */ + private LockedExecutor executor() + { + /* + * Double-checked locking to reduce the overhead of acquiring a lock + * by testing the locking criterion. + * The field (this.executor) has to be volatile. + */ + LockedExecutor executor = this.executor; + if(executor == null) + { + synchronized(this) + { + if((executor = this.executor) == null) + { + executor = this.executor = LockedExecutor.New(); + } + } + } + return executor; + } + /** * Executes an operation protected by a read lock. * @@ -38,7 +62,7 @@ protected LockScope() */ protected void read(final Action action) { - this.executor.read(action); + this.executor().read(action); } /** @@ -50,7 +74,7 @@ protected void read(final Action action) */ protected R read(final Producer producer) { - return this.executor.read(producer); + return this.executor().read(producer); } /** @@ -60,7 +84,7 @@ protected R read(final Producer producer) */ protected void write(final Action action) { - this.executor.write(action); + this.executor().write(action); } /** @@ -72,7 +96,7 @@ protected void write(final Action action) */ protected R write(final Producer producer) { - return this.executor.write(producer); + return this.executor().write(producer); } } diff --git a/base/src/main/java/org/eclipse/serializer/concurrency/StripeLockScope.java b/base/src/main/java/org/eclipse/serializer/concurrency/StripeLockScope.java index cca58bb..c2c9161 100644 --- a/base/src/main/java/org/eclipse/serializer/concurrency/StripeLockScope.java +++ b/base/src/main/java/org/eclipse/serializer/concurrency/StripeLockScope.java @@ -25,13 +25,37 @@ */ public abstract class StripeLockScope { - private final transient StripeLockedExecutor executor = StripeLockedExecutor.New(this.stripeCount()); + private transient volatile StripeLockedExecutor executor; protected StripeLockScope() { super(); } + /** + * Lazy initializes the executor. + */ + private StripeLockedExecutor executor() + { + /* + * Double-checked locking to reduce the overhead of acquiring a lock + * by testing the locking criterion. + * The field (this.executor) has to be volatile. + */ + StripeLockedExecutor executor = this.executor; + if(executor == null) + { + synchronized(this) + { + if((executor = this.executor) == null) + { + executor = this.executor = StripeLockedExecutor.New(this.stripeCount()); + } + } + } + return executor; + } + /** * Gets the maximum number of stripes used for the {@link StripeLockedExecutor}. * @@ -50,7 +74,7 @@ protected int stripeCount() */ protected void read(final Object mutex, final Action action) { - this.executor.read(mutex, action); + this.executor().read(mutex, action); } /** @@ -63,7 +87,7 @@ protected void read(final Object mutex, final Action action) */ protected R read(final Object mutex, final Producer producer) { - return this.executor.read(mutex, producer); + return this.executor().read(mutex, producer); } /** @@ -74,7 +98,7 @@ protected R read(final Object mutex, final Producer producer) */ protected void write(final Object mutex, final Action action) { - this.executor.write(mutex, action); + this.executor().write(mutex, action); } /** @@ -87,7 +111,7 @@ protected void write(final Object mutex, final Action action) */ protected R write(final Object mutex, final Producer producer) { - return this.executor.write(mutex, producer); + return this.executor().write(mutex, producer); } }