BAEL-3855

identation, moved to new module, removed needless classes, better benchmark
This commit is contained in:
Unknown 2020-02-21 14:17:46 +01:00
parent d144322c45
commit d01b7be0b6
6 changed files with 127 additions and 166 deletions

View File

@ -1,31 +1,31 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.concurrent.lock</groupId> <groupId>com.baeldung.concurrent.lock</groupId>
<artifactId>lock-striping</artifactId> <artifactId>core-java-concurrency-collections-2</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<properties> <properties>
<jmh.version>1.21</jmh.version> <jmh.version>1.21</jmh.version>
<guava.version>28.2-jre</guava.version> <guava.version>28.2-jre</guava.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>${guava.version}</version> <version>${guava.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.openjdk.jmh</groupId> <groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId> <artifactId>jmh-core</artifactId>
<version>${jmh.version}</version> <version>${jmh.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.openjdk.jmh</groupId> <groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId> <artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version> <version>${jmh.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<sourceDirectory>src</sourceDirectory> <sourceDirectory>src</sourceDirectory>

View File

@ -6,6 +6,7 @@ import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.OutputTimeUnit;
@ -16,24 +17,18 @@ import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.annotations.Warmup;
@State(Scope.Thread) @State(Scope.Thread)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.MILLISECONDS) @Fork(value = 2)
@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.MILLISECONDS) @Warmup(iterations = 3)
public class BenchMark { public class BenchMark {
ConcurrentAccessMap accessMyMap; ConcurrentAccessMap accessMyMap;
@Param({"HashMap", "HashMap with Lock", "HashMap with Striped Lock", @Param({"HashMap with Lock", "HashMap with Striped Lock",
"ConcurrentHashMap", "ConcurrentHashMap with Lock", "ConcurrentHashMap with Striped Lock"}) "ConcurrentHashMap with Lock", "ConcurrentHashMap with Striped Lock"})
private String type; private String type;
@Setup @Setup
public void setup() { public void setup() {
switch (type) { switch (type) {
case "HashMap":
accessMyMap = new NoLock(getHashMap());
break;
case "ConcurrentHashMap":
accessMyMap = new NoLock(getConcurrentHashMap());
break;
case "HashMap with Lock": case "HashMap with Lock":
accessMyMap = new CoarseGrained(getHashMap()); accessMyMap = new CoarseGrained(getHashMap());
break; break;
@ -48,19 +43,19 @@ public class BenchMark {
break; break;
} }
} }
private Map<String, String> getHashMap() { private Map<String, String> getHashMap() {
return new HashMap<String,String>(); return new HashMap<String,String>();
} }
private Map<String, String> getConcurrentHashMap() { private Map<String, String> getConcurrentHashMap() {
return new ConcurrentHashMap<String,String>(); return new ConcurrentHashMap<String,String>();
} }
@Benchmark @Benchmark
@BenchmarkMode(Mode.Throughput) @BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS) @OutputTimeUnit(TimeUnit.MILLISECONDS)
public void test() throws InterruptedException { public void test() throws InterruptedException {
accessMyMap.doWork(type); accessMyMap.doWork(type);
} }
} }

View File

@ -6,34 +6,34 @@ import java.util.concurrent.locks.ReentrantLock;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
public class CoarseGrained extends ConcurrentAccessMap { public class CoarseGrained extends ConcurrentAccessMap {
ReentrantLock lock; ReentrantLock lock;
public CoarseGrained(Map<String, String> map) { public CoarseGrained(Map<String, String> map) {
super(map); super(map);
lock = new ReentrantLock(); lock = new ReentrantLock();
} }
protected Supplier<?> putSupplier(int x) { protected Supplier<?> putSupplier(int x) {
return (()-> { return (()-> {
boolean done = false; boolean done = false;
while(!done) { while(!done) {
done = lock.tryLock(); done = lock.tryLock();
} }
map.put("key" + x, "value" + x); map.put("key" + x, "value" + x);
lock.unlock(); lock.unlock();
return null; return null;
}); });
} }
protected Supplier<?> getSupplier(int x) { protected Supplier<?> getSupplier(int x) {
return (()-> { return (()-> {
boolean done = false; boolean done = false;
while(!done) { while(!done) {
done = lock.tryLock(); done = lock.tryLock();
} }
map.get("key" + x); map.get("key" + x);
lock.unlock(); lock.unlock();
return null; return null;
}); });
} }
} }

View File

@ -6,28 +6,28 @@ import java.util.concurrent.CompletableFuture;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
public abstract class ConcurrentAccessMap { public abstract class ConcurrentAccessMap {
static final int SLOTS = 4; static final int SLOTS = 4;
static final int THREADS = 10000; static final int THREADS = 10000;
static final int BUCKETS = Runtime.getRuntime().availableProcessors() * SLOTS; static final int BUCKETS = Runtime.getRuntime().availableProcessors() * SLOTS;
private CompletableFuture<?>[] requests; private CompletableFuture<?>[] requests;
Map<String, String> map; protected Map<String, String> map;
public ConcurrentAccessMap(Map<String, String> map) { public ConcurrentAccessMap(Map<String, String> map) {
this.map = map; this.map = map;
} }
public final void doWork(String type) {
requests = new CompletableFuture<?>[THREADS * SLOTS];
for (int i = 0; i < THREADS; i++) { public final void doWork(String type) {
requests[SLOTS * i + 0] = CompletableFuture.supplyAsync(putSupplier(i)); requests = new CompletableFuture<?>[THREADS * SLOTS];
requests[SLOTS * i + 1] = CompletableFuture.supplyAsync(getSupplier(i));
requests[SLOTS * i + 2] = CompletableFuture.supplyAsync(getSupplier(i)); for (int i = 0; i < THREADS; i++) {
requests[SLOTS * i + 3] = CompletableFuture.supplyAsync(getSupplier(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(); CompletableFuture.allOf(requests).join();
} }
protected abstract Supplier<?> putSupplier(int x); protected abstract Supplier<?> putSupplier(int x);
protected abstract Supplier<?> getSupplier(int x); protected abstract Supplier<?> getSupplier(int x);
} }

View File

@ -7,41 +7,41 @@ import com.google.common.base.Supplier;
import com.google.common.util.concurrent.Striped; import com.google.common.util.concurrent.Striped;
public class LockStriped extends ConcurrentAccessMap { public class LockStriped extends ConcurrentAccessMap {
Striped<Lock> lock; Striped<Lock> lock;
public LockStriped(Map<String, String> map) { public LockStriped(Map<String, String> map) {
super(map); super(map);
lock = getStripedLock(); lock = getStripedLock();
} }
private Striped<Lock> getStripedLock() { private Striped<Lock> getStripedLock() {
Striped<Lock> map = Striped.lock(BUCKETS); Striped<Lock> map = Striped.lock(BUCKETS);
return map; return map;
} }
protected Supplier<?> putSupplier(int x) { protected Supplier<?> putSupplier(int x) {
return (()-> { return (()-> {
Lock currentLock = lock.get("key" + x); Lock currentLock = lock.get("key" + x);
boolean done = false; boolean done = false;
while(!done) { while(!done) {
done = currentLock.tryLock(); done = currentLock.tryLock();
} }
map.put("key" + x, "value" + x); map.put("key" + x, "value" + x);
currentLock.unlock(); currentLock.unlock();
return null; return null;
}); });
} }
protected Supplier<?> getSupplier(int x) { protected Supplier<?> getSupplier(int x) {
return (()-> { return (()-> {
Lock currentLock = lock.get("key" + x); Lock currentLock = lock.get("key" + x);
boolean done = false; boolean done = false;
while(!done) { while(!done) {
done = currentLock.tryLock(); done = currentLock.tryLock();
} }
map.get("key" + x); map.get("key" + x);
currentLock.unlock(); currentLock.unlock();
return null; return null;
}); });
} }
} }

View File

@ -1,34 +0,0 @@
package com.baeldung.concurrent.lock;
import java.util.Map;
import com.google.common.base.Supplier;
public class NoLock extends ConcurrentAccessMap {
public NoLock(Map<String, String> 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;
});
}
}