diff --git a/base/src/main/java/org/eclipse/serializer/concurrency/LockScope.java b/base/src/main/java/org/eclipse/serializer/concurrency/LockScope.java
new file mode 100644
index 00000000..4905164c
--- /dev/null
+++ b/base/src/main/java/org/eclipse/serializer/concurrency/LockScope.java
@@ -0,0 +1,78 @@
+package org.eclipse.serializer.concurrency;
+
+/*-
+ * #%L
+ * Eclipse Serializer Base
+ * %%
+ * Copyright (C) 2024 MicroStream Software
+ * %%
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * #L%
+ */
+
+import org.eclipse.serializer.functional.Action;
+import org.eclipse.serializer.functional.Producer;
+
+/**
+ * Abstract base class for types, which want to utilize a {@link LockedExecutor}.
+ *
+ * All the executor's methods are exposed by abstract equivalents inside this type hierarchy.
+ */
+public abstract class LockScope
+{
+ private final transient LockedExecutor executor = LockedExecutor.New();
+
+ protected LockScope()
+ {
+ super();
+ }
+
+ /**
+ * Executes an operation protected by a read lock.
+ *
+ * @param action the action to execute
+ */
+ protected void read(final Action action)
+ {
+ this.executor.read(action);
+ }
+
+ /**
+ * Executes an operation protected by a read lock.
+ *
+ * @param the producer's return type
+ * @param producer the producer to execute
+ * @return the producer's result
+ */
+ protected R read(final Producer producer)
+ {
+ return this.executor.read(producer);
+ }
+
+ /**
+ * Executes an operation protected by a write lock.
+ *
+ * @param action the action to execute
+ */
+ protected void write(final Action action)
+ {
+ this.executor.write(action);
+ }
+
+ /**
+ * Executes an operation protected by a write lock.
+ *
+ * @param the producer's return type
+ * @param producer the producer to execute
+ * @return the producer's result
+ */
+ protected R write(final Producer producer)
+ {
+ return this.executor.write(producer);
+ }
+
+}
diff --git a/base/src/main/java/org/eclipse/serializer/concurrency/LockedExecutor.java b/base/src/main/java/org/eclipse/serializer/concurrency/LockedExecutor.java
new file mode 100644
index 00000000..cc13ba48
--- /dev/null
+++ b/base/src/main/java/org/eclipse/serializer/concurrency/LockedExecutor.java
@@ -0,0 +1,224 @@
+package org.eclipse.serializer.concurrency;
+
+/*-
+ * #%L
+ * Eclipse Serializer Base
+ * %%
+ * Copyright (C) 2024 MicroStream Software
+ * %%
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * #L%
+ */
+
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+
+import org.eclipse.serializer.functional.Action;
+import org.eclipse.serializer.functional.Producer;
+
+
+/**
+ * Facility to execute operations with a reentrant mutual exclusion.
+ *
+ * @see ReentrantLock
+ * @see ReadWriteLock
+ */
+public interface LockedExecutor
+{
+ /**
+ * Executes an operation protected by a read lock.
+ *
+ * @param action the action to execute
+ */
+ public void read(Action action);
+
+ /**
+ * Executes an operation protected by a read lock.
+ *
+ * @param the producer's return type
+ * @param producer the producer to execute
+ * @return the producer's result
+ */
+ public R read(Producer producer);
+
+ /**
+ * Executes an operation protected by a write lock.
+ *
+ * @param action the action to execute
+ */
+ public void write(Action action);
+
+ /**
+ * Executes an operation protected by a write lock.
+ *
+ * @param the producer's return type
+ * @param producer the producer to execute
+ * @return the producer's result
+ */
+ public R write(Producer producer);
+
+
+
+ public static final class Static
+ {
+ private final static Object LOCK = new Object();
+ private static volatile LockedExecutor sharedInstance;
+
+ public static LockedExecutor sharedInstance()
+ {
+ /*
+ * Double-checked locking to reduce the overhead of acquiring a lock
+ * by testing the locking criterion.
+ * The field (Static.sharedInstance) has to be volatile.
+ */
+ LockedExecutor sharedInstance = Static.sharedInstance;
+ if(sharedInstance == null)
+ {
+ synchronized(LOCK)
+ {
+ if((sharedInstance = Static.sharedInstance) == null)
+ {
+ sharedInstance = Static.sharedInstance = LockedExecutor.New();
+ }
+ }
+ }
+ return sharedInstance;
+ }
+
+
+ private Static()
+ {
+ // static only
+ throw new UnsupportedOperationException();
+ }
+ }
+
+
+ /**
+ * Provides a global {@link LockedExecutor} instance.
+ *
+ * Only a single one exists for the whole VM process, meaning it can be used to create VM-wide locks.
+ *
+ * @return a shared {@link LockedExecutor} instance
+ */
+ public static LockedExecutor global()
+ {
+ return Static.sharedInstance();
+ }
+
+
+ /**
+ * Pseudo-constructor method to create a new {@link LockedExecutor}.
+ *
+ * @return a newly created {@link LockedExecutor}
+ */
+ public static LockedExecutor New()
+ {
+ return new LockedExecutor.Default();
+ }
+
+
+ public static class Default implements LockedExecutor
+ {
+ private transient volatile ReentrantReadWriteLock reentrantLock;
+
+ Default()
+ {
+ super();
+ }
+
+ private ReentrantReadWriteLock reentrantLock()
+ {
+ /*
+ * Double-checked locking to reduce the overhead of acquiring a lock
+ * by testing the locking criterion.
+ * The field (this.reentrantLock) has to be volatile.
+ */
+ ReentrantReadWriteLock reentrantLock = this.reentrantLock;
+ if(reentrantLock == null)
+ {
+ synchronized(this)
+ {
+ if((reentrantLock = this.reentrantLock) == null)
+ {
+ reentrantLock = this.reentrantLock = new ReentrantReadWriteLock();
+ }
+ }
+ }
+ return reentrantLock;
+ }
+
+ @Override
+ public void read(final Action action)
+ {
+ final ReadLock readLock = this.reentrantLock().readLock();
+ readLock.lock();
+
+ try
+ {
+ action.execute();
+ }
+ finally
+ {
+ readLock.unlock();
+ }
+ }
+
+ @Override
+ public T read(final Producer producer)
+ {
+ final ReadLock readLock = this.reentrantLock().readLock();
+ readLock.lock();
+
+ try
+ {
+ return producer.produce();
+ }
+ finally
+ {
+ readLock.unlock();
+ }
+ }
+
+ @Override
+ public void write(final Action action)
+ {
+ final WriteLock writeLock = this.reentrantLock().writeLock();
+ writeLock.lock();
+
+ try
+ {
+ action.execute();
+ }
+ finally
+ {
+ writeLock.unlock();
+ }
+ }
+
+ @Override
+ public R write(final Producer producer)
+ {
+ final WriteLock writeLock = this.reentrantLock().writeLock();
+ writeLock.lock();
+
+ try
+ {
+ return producer.produce();
+ }
+ finally
+ {
+ writeLock.unlock();
+ }
+ }
+
+ }
+
+}
diff --git a/base/src/main/java/org/eclipse/serializer/concurrency/StripeLockScope.java b/base/src/main/java/org/eclipse/serializer/concurrency/StripeLockScope.java
new file mode 100644
index 00000000..cca58bb6
--- /dev/null
+++ b/base/src/main/java/org/eclipse/serializer/concurrency/StripeLockScope.java
@@ -0,0 +1,93 @@
+package org.eclipse.serializer.concurrency;
+
+/*-
+ * #%L
+ * Eclipse Serializer Base
+ * %%
+ * Copyright (C) 2024 MicroStream Software
+ * %%
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * #L%
+ */
+
+import org.eclipse.serializer.functional.Action;
+import org.eclipse.serializer.functional.Producer;
+
+
+/**
+ * Abstract base class for types, which want to utilize a {@link StripeLockedExecutor}.
+ *
+ * All the executor's methods are exposed by abstract equivalents inside this type hierarchy.
+ */
+public abstract class StripeLockScope
+{
+ private final transient StripeLockedExecutor executor = StripeLockedExecutor.New(this.stripeCount());
+
+ protected StripeLockScope()
+ {
+ super();
+ }
+
+ /**
+ * Gets the maximum number of stripes used for the {@link StripeLockedExecutor}.
+ *
+ * @return max number of stripes
+ */
+ protected int stripeCount()
+ {
+ return Runtime.getRuntime().availableProcessors();
+ }
+
+ /**
+ * Executes an operation protected by a read lock.
+ *
+ * @param mutex the mutex to lock on, not null
+ * @param action the action to execute
+ */
+ protected void read(final Object mutex, final Action action)
+ {
+ this.executor.read(mutex, action);
+ }
+
+ /**
+ * Executes an operation protected by a read lock.
+ *
+ * @param the producer's return type
+ * @param mutex the mutex to lock on, not null
+ * @param producer the producer to execute
+ * @return the producer's result
+ */
+ protected R read(final Object mutex, final Producer producer)
+ {
+ return this.executor.read(mutex, producer);
+ }
+
+ /**
+ * Executes an operation protected by a write lock.
+ *
+ * @param mutex the mutex to lock on, not null
+ * @param action the action to execute
+ */
+ protected void write(final Object mutex, final Action action)
+ {
+ this.executor.write(mutex, action);
+ }
+
+ /**
+ * Executes an operation protected by a write lock.
+ *
+ * @param the producer's return type
+ * @param mutex the mutex to lock on, not null
+ * @param producer the producer to execute
+ * @return the producer's result
+ */
+ protected R write(final Object mutex, final Producer producer)
+ {
+ return this.executor.write(mutex, producer);
+ }
+
+}
diff --git a/base/src/main/java/org/eclipse/serializer/concurrency/StripeLockedExecutor.java b/base/src/main/java/org/eclipse/serializer/concurrency/StripeLockedExecutor.java
new file mode 100644
index 00000000..940c7f0c
--- /dev/null
+++ b/base/src/main/java/org/eclipse/serializer/concurrency/StripeLockedExecutor.java
@@ -0,0 +1,241 @@
+package org.eclipse.serializer.concurrency;
+
+/*-
+ * #%L
+ * Eclipse Serializer Base
+ * %%
+ * Copyright (C) 2024 MicroStream Software
+ * %%
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * #L%
+ */
+
+import static java.lang.Math.abs;
+import static org.eclipse.serializer.math.XMath.positive;
+
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+
+import org.eclipse.serializer.functional.Action;
+import org.eclipse.serializer.functional.Producer;
+
+
+/**
+ * Facility to execute operations with a reentrant mutual exclusion for defined mutexes.
+ *
+ * @see ReentrantLock
+ * @see ReadWriteLock
+ */
+public interface StripeLockedExecutor
+{
+ /**
+ * Executes an operation protected by a read lock.
+ *
+ * @param mutex the mutex to lock on, not null
+ * @param action the action to execute
+ */
+ public void read(Object mutex, Action action);
+
+ /**
+ * Executes an operation protected by a read lock.
+ *
+ * @param the producer's return type
+ * @param mutex the mutex to lock on, not null
+ * @param producer the producer to execute
+ * @return the producer's result
+ */
+ public R read(Object mutex, Producer producer);
+
+ /**
+ * Executes an operation protected by a write lock.
+ *
+ * @param mutex the mutex to lock on, not null
+ * @param action the action to execute
+ */
+ public void write(Object mutex, Action action);
+
+ /**
+ * Executes an operation protected by a write lock.
+ *
+ * @param the producer's return type
+ * @param mutex the mutex to lock on, not null
+ * @param producer the producer to execute
+ * @return the producer's result
+ */
+ public R write(Object mutex, Producer producer);
+
+
+
+ public static final class Static
+ {
+ private final static Object LOCK = new Object();
+ private static volatile StripeLockedExecutor sharedInstance;
+
+ public static StripeLockedExecutor sharedInstance()
+ {
+ /*
+ * Double-checked locking to reduce the overhead of acquiring a lock
+ * by testing the locking criterion.
+ * The field (Static.sharedInstance) has to be volatile.
+ */
+ StripeLockedExecutor sharedInstance = Static.sharedInstance;
+ if(sharedInstance == null)
+ {
+ synchronized(LOCK)
+ {
+ if((sharedInstance = Static.sharedInstance) == null)
+ {
+ sharedInstance = Static.sharedInstance = StripeLockedExecutor.New(
+ Runtime.getRuntime().availableProcessors()
+ );
+ }
+ }
+ }
+ return sharedInstance;
+ }
+
+
+ private Static()
+ {
+ // static only
+ throw new UnsupportedOperationException();
+ }
+ }
+
+
+ /**
+ * Provides a global {@link StripeLockedExecutor} instance.
+ *
+ * Only a single one exists for the whole VM process, meaning it can be used to create VM-wide locks.
+ *
+ * @return a shared {@link StripeLockedExecutor} instance
+ */
+ public static StripeLockedExecutor global()
+ {
+ return Static.sharedInstance();
+ }
+
+
+
+ /**
+ * Pseudo-constructor method to create a new {@link StripeLockedExecutor}.
+ *
+ * @param stripeCount maximum number of stripes
+ * @return a newly created {@link StripeLockedExecutor}
+ */
+ public static StripeLockedExecutor New(final int stripeCount)
+ {
+ return new StripeLockedExecutor.Default(
+ positive(stripeCount)
+ );
+ }
+
+
+ public static class Default implements StripeLockedExecutor
+ {
+ private transient volatile ReentrantReadWriteLock[] reentrantLocks;
+
+ Default(final int stripeCount)
+ {
+ super();
+
+ this.reentrantLocks = new ReentrantReadWriteLock[stripeCount];
+ }
+
+ private ReentrantReadWriteLock reentrantLock(final Object mutex)
+ {
+ /*
+ * Double-checked locking to reduce the overhead of acquiring a lock
+ * by testing the locking criterion.
+ * The field (this.reentrantLocks) has to be volatile.
+ */
+
+ final int index = abs(mutex.hashCode()) % this.reentrantLocks.length;
+ ReentrantReadWriteLock reentrantLock = this.reentrantLocks[index];
+ if(reentrantLock == null)
+ {
+ synchronized(this)
+ {
+ if((reentrantLock = this.reentrantLocks[index]) == null)
+ {
+ reentrantLock = this.reentrantLocks[index] = new ReentrantReadWriteLock();
+ }
+ }
+ }
+ return reentrantLock;
+ }
+
+ @Override
+ public void read(final Object mutex, final Action action)
+ {
+ final ReadLock readLock = this.reentrantLock(mutex).readLock();
+ readLock.lock();
+
+ try
+ {
+ action.execute();
+ }
+ finally
+ {
+ readLock.unlock();
+ }
+ }
+
+ @Override
+ public T read(final Object mutex, final Producer producer)
+ {
+ final ReadLock readLock = this.reentrantLock(mutex).readLock();
+ readLock.lock();
+
+ try
+ {
+ return producer.produce();
+ }
+ finally
+ {
+ readLock.unlock();
+ }
+ }
+
+ @Override
+ public void write(final Object mutex, final Action action)
+ {
+ final WriteLock writeLock = this.reentrantLock(mutex).writeLock();
+ writeLock.lock();
+
+ try
+ {
+ action.execute();
+ }
+ finally
+ {
+ writeLock.unlock();
+ }
+ }
+
+ @Override
+ public R write(final Object mutex, final Producer producer)
+ {
+ final WriteLock writeLock = this.reentrantLock(mutex).writeLock();
+ writeLock.lock();
+
+ try
+ {
+ return producer.produce();
+ }
+ finally
+ {
+ writeLock.unlock();
+ }
+ }
+
+ }
+
+}
diff --git a/base/src/main/java/org/eclipse/serializer/functional/Producer.java b/base/src/main/java/org/eclipse/serializer/functional/Producer.java
new file mode 100644
index 00000000..4bb19afa
--- /dev/null
+++ b/base/src/main/java/org/eclipse/serializer/functional/Producer.java
@@ -0,0 +1,21 @@
+package org.eclipse.serializer.functional;
+
+/*-
+ * #%L
+ * Eclipse Serializer Base
+ * %%
+ * Copyright (C) 2024 MicroStream Software
+ * %%
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * #L%
+ */
+
+@FunctionalInterface
+public interface Producer
+{
+ public R produce();
+}