diff --git a/core-java-modules/core-java-concurrency-collections-2/src/main/java/com/baeldung/concurrent/lock/ConcurrentAccessBenchmark.java b/core-java-modules/core-java-concurrency-collections-2/src/main/java/com/baeldung/concurrent/lock/ConcurrentAccessBenchmark.java new file mode 100644 index 0000000000..7c84c39804 --- /dev/null +++ b/core-java-modules/core-java-concurrency-collections-2/src/main/java/com/baeldung/concurrent/lock/ConcurrentAccessBenchmark.java @@ -0,0 +1,49 @@ +package com.baeldung.concurrent.lock; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +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) +@Fork(value = 1) +@Warmup(iterations = 0) +public class ConcurrentAccessBenchmark { + ConcurrentAccessExperiment accessMyMap; + static final int SLOTS = 4; + static final int THREADS = 10000; + static final int BUCKETS = Runtime.getRuntime().availableProcessors() * SLOTS; + + @Param({"Single Lock", "Striped Lock"}) + private String lockType; + + @Param({"HashMap", "ConcurrentHashMap"}) + private String mapType; + + @Setup + public void setup() { + switch (lockType) { + case "Single Lock": + accessMyMap = new SingleLock(); + break; + case "Striped Lock": + accessMyMap = new StripedLock(BUCKETS); + break; + } + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void test() throws InterruptedException { + accessMyMap.doWork(mapType, THREADS, SLOTS); + } +} diff --git a/core-java-modules/core-java-concurrency-collections-2/src/main/java/com/baeldung/concurrent/lock/ConcurrentAccessExperiment.java b/core-java-modules/core-java-concurrency-collections-2/src/main/java/com/baeldung/concurrent/lock/ConcurrentAccessExperiment.java new file mode 100644 index 0000000000..b1276410ce --- /dev/null +++ b/core-java-modules/core-java-concurrency-collections-2/src/main/java/com/baeldung/concurrent/lock/ConcurrentAccessExperiment.java @@ -0,0 +1,40 @@ +package com.baeldung.concurrent.lock; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +import com.google.common.base.Supplier; + +public abstract class ConcurrentAccessExperiment { + + public ConcurrentAccessExperiment() { + } + + private Map doMapSetup(String typeOfMap) { + switch (typeOfMap) { + case "HashMap": + return new HashMap(); + case "ConcurrentHashMap": + return new ConcurrentHashMap(); + } + return null; + } + + public final void doWork(String typeOfMap, int threads, int slots) { + CompletableFuture[] requests = new CompletableFuture[threads * slots]; + Map map = doMapSetup(typeOfMap); + + for (int i = 0; i < threads; i++) { + requests[slots * i + 0] = CompletableFuture.supplyAsync(putSupplier(map, i)); + requests[slots * i + 1] = CompletableFuture.supplyAsync(getSupplier(map, i)); + requests[slots * i + 2] = CompletableFuture.supplyAsync(getSupplier(map, i)); + requests[slots * i + 3] = CompletableFuture.supplyAsync(getSupplier(map, i)); + } + CompletableFuture.allOf(requests).join(); + } + + protected abstract Supplier putSupplier(Map map, int key); + protected abstract Supplier getSupplier(Map map, int key); +} \ No newline at end of file