BAEL-3855
This commit is contained in:
parent
52608c32cb
commit
ff4ac10bb2
@ -1,48 +0,0 @@
|
|||||||
package main.java.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 BenchMark {
|
|
||||||
ConcurrentAccessMap accessMyMap;
|
|
||||||
static final int SLOTS = 4;
|
|
||||||
static final int THREADS = 1000;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package main.java.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 ConcurrentAccessMap {
|
|
||||||
|
|
||||||
public ConcurrentAccessMap() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> getHashMap() {
|
|
||||||
return new HashMap<String,String>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> getConcurrentHashMap() {
|
|
||||||
return new ConcurrentHashMap<String,String>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String,String> setup(String type) {
|
|
||||||
switch (type) {
|
|
||||||
case "HashMap":
|
|
||||||
return getHashMap();
|
|
||||||
case "ConcurrentHashMap":
|
|
||||||
return getConcurrentHashMap();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void doWork(String type, int threads, int slots) {
|
|
||||||
CompletableFuture<?>[] requests = new CompletableFuture<?>[threads * slots];
|
|
||||||
Map<String,String> map = setup(type);
|
|
||||||
|
|
||||||
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<String,String> map, int key);
|
|
||||||
protected abstract Supplier<?> getSupplier(Map<String,String> map, int key);
|
|
||||||
}
|
|
@ -1,11 +1,11 @@
|
|||||||
package main.java.com.baeldung.concurrent.lock;
|
package com.baeldung.concurrent.lock;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
public class SingleLock extends ConcurrentAccessMap {
|
public class SingleLock extends ConcurrentAccessExperiment {
|
||||||
ReentrantLock lock;
|
ReentrantLock lock;
|
||||||
|
|
||||||
public SingleLock() {
|
public SingleLock() {
|
||||||
@ -15,11 +15,14 @@ public class SingleLock extends ConcurrentAccessMap {
|
|||||||
protected synchronized Supplier<?> putSupplier(Map<String,String> map, int key) {
|
protected synchronized Supplier<?> putSupplier(Map<String,String> map, int key) {
|
||||||
return (()-> {
|
return (()-> {
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
|
try {
|
||||||
while(!done) {
|
while(!done) {
|
||||||
done = lock.tryLock();
|
done = lock.tryLock();
|
||||||
}
|
}
|
||||||
map.put("key" + key, "value" + key);
|
map.put("key" + key, "value" + key);
|
||||||
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -27,11 +30,14 @@ public class SingleLock extends ConcurrentAccessMap {
|
|||||||
protected synchronized Supplier<?> getSupplier(Map<String,String> map, int key) {
|
protected synchronized Supplier<?> getSupplier(Map<String,String> map, int key) {
|
||||||
return (()-> {
|
return (()-> {
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
|
try {
|
||||||
while(!done) {
|
while(!done) {
|
||||||
done = lock.tryLock();
|
done = lock.tryLock();
|
||||||
}
|
}
|
||||||
map.get("key" + key);
|
map.get("key" + key);
|
||||||
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package main.java.com.baeldung.concurrent.lock;
|
package com.baeldung.concurrent.lock;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
@ -6,7 +6,7 @@ import java.util.concurrent.locks.Lock;
|
|||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.util.concurrent.Striped;
|
import com.google.common.util.concurrent.Striped;
|
||||||
|
|
||||||
public class StripedLock extends ConcurrentAccessMap {
|
public class StripedLock extends ConcurrentAccessExperiment {
|
||||||
Striped<Lock> lock;
|
Striped<Lock> lock;
|
||||||
|
|
||||||
public StripedLock(int buckets) {
|
public StripedLock(int buckets) {
|
||||||
@ -22,11 +22,14 @@ public class StripedLock extends ConcurrentAccessMap {
|
|||||||
return (()-> {
|
return (()-> {
|
||||||
Lock currentLock = lock.get("key" + key);
|
Lock currentLock = lock.get("key" + key);
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
|
try {
|
||||||
while(!done) {
|
while(!done) {
|
||||||
done = currentLock.tryLock();
|
done = currentLock.tryLock();
|
||||||
}
|
}
|
||||||
map.put("key" + key, "value" + key);
|
map.put("key" + key, "value" + key);
|
||||||
|
} finally {
|
||||||
currentLock.unlock();
|
currentLock.unlock();
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -35,11 +38,14 @@ public class StripedLock extends ConcurrentAccessMap {
|
|||||||
return (()-> {
|
return (()-> {
|
||||||
Lock currentLock = lock.get("key" + key);
|
Lock currentLock = lock.get("key" + key);
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
|
try {
|
||||||
while(!done) {
|
while(!done) {
|
||||||
done = currentLock.tryLock();
|
done = currentLock.tryLock();
|
||||||
}
|
}
|
||||||
map.get("key" + key);
|
map.get("key" + key);
|
||||||
|
} finally {
|
||||||
currentLock.unlock();
|
currentLock.unlock();
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user