diff --git a/lock-striping/pom.xml b/lock-striping/pom.xml
new file mode 100644
index 0000000000..79469593cf
--- /dev/null
+++ b/lock-striping/pom.xml
@@ -0,0 +1,43 @@
+
+ 4.0.0
+ com.baeldung.concurrent.lock
+ lock-striping
+ 0.0.1-SNAPSHOT
+
+
+ 1.21
+ 28.2-jre
+
+
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+ org.openjdk.jmh
+ jmh-core
+ ${jmh.version}
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh.version}
+
+
+
+
+ src
+
+
+ maven-compiler-plugin
+ 3.8.0
+
+ 1.8
+ 1.8
+
+
+
+
+
\ No newline at end of file
diff --git a/lock-striping/src/com/baeldung/concurrent/lock/BenchMark.java b/lock-striping/src/com/baeldung/concurrent/lock/BenchMark.java
new file mode 100644
index 0000000000..5aae5145d2
--- /dev/null
+++ b/lock-striping/src/com/baeldung/concurrent/lock/BenchMark.java
@@ -0,0 +1,66 @@
+package com.baeldung.concurrent.lock;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+@State(Scope.Thread)
+@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.MILLISECONDS)
+@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.MILLISECONDS)
+public class BenchMark {
+ ConcurrentAccessMap accessMyMap;
+
+ @Param({"HashMap", "HashMap with Lock", "HashMap with Striped Lock",
+ "ConcurrentHashMap", "ConcurrentHashMap with Lock", "ConcurrentHashMap with Striped Lock"})
+ private String type;
+
+ @Setup
+ public void setup() {
+ switch (type) {
+ case "HashMap":
+ accessMyMap = new NoLock(getHashMap());
+ break;
+ case "ConcurrentHashMap":
+ accessMyMap = new NoLock(getConcurrentHashMap());
+ break;
+ case "HashMap with Lock":
+ accessMyMap = new CoarseGrained(getHashMap());
+ break;
+ case "ConcurrentHashMap with Lock":
+ accessMyMap = new CoarseGrained(getConcurrentHashMap());
+ break;
+ case "HashMap with Striped Lock":
+ accessMyMap = new LockStriped(getHashMap());
+ break;
+ case "ConcurrentHashMap with Striped Lock":
+ accessMyMap = new LockStriped(getConcurrentHashMap());
+ break;
+ }
+ }
+
+ private Map getHashMap() {
+ return new HashMap();
+ }
+
+ private Map getConcurrentHashMap() {
+ return new ConcurrentHashMap();
+ }
+
+ @Benchmark
+ @BenchmarkMode(Mode.Throughput)
+ @OutputTimeUnit(TimeUnit.MILLISECONDS)
+ public void test() throws InterruptedException {
+ accessMyMap.doWork(type);
+ }
+}
diff --git a/lock-striping/src/com/baeldung/concurrent/lock/CoarseGrained.java b/lock-striping/src/com/baeldung/concurrent/lock/CoarseGrained.java
new file mode 100644
index 0000000000..adc70fc3ab
--- /dev/null
+++ b/lock-striping/src/com/baeldung/concurrent/lock/CoarseGrained.java
@@ -0,0 +1,39 @@
+package com.baeldung.concurrent.lock;
+
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
+
+import com.google.common.base.Supplier;
+
+public class CoarseGrained extends ConcurrentAccessMap {
+ ReentrantLock lock;
+
+ public CoarseGrained(Map map) {
+ super(map);
+ lock = new ReentrantLock();
+ }
+
+ protected Supplier> putSupplier(int x) {
+ return (()-> {
+ boolean done = false;
+ while(!done) {
+ done = lock.tryLock();
+ }
+ map.put("key" + x, "value" + x);
+ lock.unlock();
+ return null;
+ });
+ }
+
+ protected Supplier> getSupplier(int x) {
+ return (()-> {
+ boolean done = false;
+ while(!done) {
+ done = lock.tryLock();
+ }
+ map.get("key" + x);
+ lock.unlock();
+ return null;
+ });
+ }
+}
diff --git a/lock-striping/src/com/baeldung/concurrent/lock/ConcurrentAccessMap.java b/lock-striping/src/com/baeldung/concurrent/lock/ConcurrentAccessMap.java
new file mode 100644
index 0000000000..87c305b8aa
--- /dev/null
+++ b/lock-striping/src/com/baeldung/concurrent/lock/ConcurrentAccessMap.java
@@ -0,0 +1,33 @@
+package com.baeldung.concurrent.lock;
+
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+import com.google.common.base.Supplier;
+
+public abstract class ConcurrentAccessMap {
+ static final int SLOTS = 4;
+ static final int THREADS = 10000;
+ static final int BUCKETS = Runtime.getRuntime().availableProcessors() * SLOTS;
+ private CompletableFuture>[] requests;
+ Map map;
+
+ public ConcurrentAccessMap(Map map) {
+ this.map = map;
+ }
+
+ public final void doWork(String type) {
+ requests = new CompletableFuture>[THREADS * SLOTS];
+
+ for (int i = 0; i < THREADS; i++) {
+ requests[SLOTS * i + 0] = CompletableFuture.supplyAsync(putSupplier(i));
+ requests[SLOTS * i + 1] = CompletableFuture.supplyAsync(getSupplier(i));
+ requests[SLOTS * i + 2] = CompletableFuture.supplyAsync(getSupplier(i));
+ requests[SLOTS * i + 3] = CompletableFuture.supplyAsync(getSupplier(i));
+ }
+ CompletableFuture.allOf(requests).join();
+ }
+
+ protected abstract Supplier> putSupplier(int x);
+ protected abstract Supplier> getSupplier(int x);
+}
diff --git a/lock-striping/src/com/baeldung/concurrent/lock/LockStriped.java b/lock-striping/src/com/baeldung/concurrent/lock/LockStriped.java
new file mode 100644
index 0000000000..91d72eb362
--- /dev/null
+++ b/lock-striping/src/com/baeldung/concurrent/lock/LockStriped.java
@@ -0,0 +1,47 @@
+package com.baeldung.concurrent.lock;
+
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+
+import com.google.common.base.Supplier;
+import com.google.common.util.concurrent.Striped;
+
+public class LockStriped extends ConcurrentAccessMap {
+ Striped lock;
+
+ public LockStriped(Map map) {
+ super(map);
+ lock = getStripedLock();
+ }
+
+ private Striped getStripedLock() {
+ Striped map = Striped.lock(BUCKETS);
+ return map;
+ }
+
+ protected Supplier> putSupplier(int x) {
+ return (()-> {
+ Lock currentLock = lock.get("key" + x);
+ boolean done = false;
+ while(!done) {
+ done = currentLock.tryLock();
+ }
+ map.put("key" + x, "value" + x);
+ currentLock.unlock();
+ return null;
+ });
+ }
+
+ protected Supplier> getSupplier(int x) {
+ return (()-> {
+ Lock currentLock = lock.get("key" + x);
+ boolean done = false;
+ while(!done) {
+ done = currentLock.tryLock();
+ }
+ map.get("key" + x);
+ currentLock.unlock();
+ return null;
+ });
+ }
+}
diff --git a/lock-striping/src/com/baeldung/concurrent/lock/NoLock.java b/lock-striping/src/com/baeldung/concurrent/lock/NoLock.java
new file mode 100644
index 0000000000..f2d5b445d7
--- /dev/null
+++ b/lock-striping/src/com/baeldung/concurrent/lock/NoLock.java
@@ -0,0 +1,34 @@
+package com.baeldung.concurrent.lock;
+
+import java.util.Map;
+
+import com.google.common.base.Supplier;
+
+public class NoLock extends ConcurrentAccessMap {
+
+ public NoLock(Map map) {
+ super(map);
+ }
+
+ protected Supplier> putSupplier(int x) {
+ return (()-> {
+ boolean done = false;
+ while(!done) {
+ map.put("key" + x, "value" + x);
+ done = true;
+ }
+ return null;
+ });
+ }
+
+ protected Supplier> getSupplier(int x) {
+ return (()-> {
+ boolean done = false;
+ while(!done) {
+ map.get("key" + x);
+ done = true;
+ }
+ return null;
+ });
+ }
+}
\ No newline at end of file