Merge branch 'master' of https://github.com/vikasrajput6035/tutorials into BAEL-3832

This commit is contained in:
Vikas Ramsingh Rajput 2020-03-21 09:16:32 +03:00
commit a32b8b39b6
7 changed files with 208 additions and 4 deletions

View File

@ -0,0 +1,43 @@
<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>
<groupId>com.baeldung.concurrent.lock</groupId>
<artifactId>core-java-concurrency-collections-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<jmh.version>1.21</jmh.version>
<guava.version>28.2-jre</guava.version>
</properties>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,54 @@
package com.baeldung.concurrent.lock;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.Map;
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.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
@State(Scope.Thread)
@Fork(value = 2)
@Warmup(iterations = 0)
public class ConcurrentAccessBenchmark {
static final int SLOTS = 4;
static final int THREADS = 10000;
static final int BUCKETS = Runtime.getRuntime().availableProcessors() * SLOTS;
SingleLock singleLock = new SingleLock();
StripedLock stripedLock = new StripedLock(BUCKETS);
@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public Map<String,String> singleLockHashMap() throws InterruptedException {
return singleLock.doWork(new HashMap<String,String>(), THREADS, SLOTS);
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public Map<String,String> stripedLockHashMap() throws InterruptedException {
return stripedLock.doWork(new HashMap<String,String>(), THREADS, SLOTS);
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public Map<String,String> singleLockConcurrentHashMap() throws InterruptedException {
return singleLock.doWork(new ConcurrentHashMap<String,String>(), THREADS, SLOTS);
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public Map<String,String> stripedLockConcurrentHashMap() throws InterruptedException {
return stripedLock.doWork(new ConcurrentHashMap<String,String>(), THREADS, SLOTS);
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.concurrent.lock;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import com.google.common.base.Supplier;
public abstract class ConcurrentAccessExperiment {
public final Map<String,String> doWork(Map<String,String> map, int threads, int slots) {
CompletableFuture<?>[] requests = new CompletableFuture<?>[threads * slots];
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();
return map;
}
protected abstract Supplier<?> putSupplier(Map<String,String> map, int key);
protected abstract Supplier<?> getSupplier(Map<String,String> map, int key);
}

View File

@ -0,0 +1,36 @@
package com.baeldung.concurrent.lock;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import com.google.common.base.Supplier;
public class SingleLock extends ConcurrentAccessExperiment {
ReentrantLock lock;
public SingleLock() {
lock = new ReentrantLock();
}
protected Supplier<?> putSupplier(Map<String,String> map, int key) {
return (()-> {
lock.lock();
try {
return map.put("key" + key, "value" + key);
} finally {
lock.unlock();
}
});
}
protected Supplier<?> getSupplier(Map<String,String> map, int key) {
return (()-> {
lock.lock();
try {
return map.get("key" + key);
} finally {
lock.unlock();
}
});
}
}

View File

@ -0,0 +1,41 @@
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 StripedLock extends ConcurrentAccessExperiment {
Striped<Lock> stripedLock;
public StripedLock(int buckets) {
stripedLock = Striped.lock(buckets);
}
protected Supplier<?> putSupplier(Map<String,String> map, int key) {
return (()-> {
int bucket = key % stripedLock.size();
Lock lock = stripedLock.get(bucket);
lock.lock();
try {
return map.put("key" + key, "value" + key);
} finally {
lock.unlock();
}
});
}
protected Supplier<?> getSupplier(Map<String,String> map, int key) {
return (()-> {
int bucket = key % stripedLock.size();
Lock lock = stripedLock.get(bucket);
lock.lock();
try {
return map.get("key" + key);
} finally {
lock.unlock();
}
});
}
}

View File

@ -52,14 +52,13 @@ public class ConsumerFooServiceIntegrationTest {
.map(Arrays::stream)
.orElse(Stream.empty());
})
.map(IThrowableProxy::getMessage)
.map(IThrowableProxy::getClassName)
.collect(Collectors.toList());
assertThat(allLoggedEntries).anyMatch(entry -> entry.contains("The following error happened on processFoo method!"))
.anyMatch(entry -> entry.contains("| onSubscribe"))
.anyMatch(entry -> entry.contains("| cancel()"));
assertThat(allSuppressedEntries).anyMatch(entry -> entry.contains("Assembly trace from producer"))
.anyMatch(entry -> entry.contains("Error has been observed by the following operator(s)"));
assertThat(allSuppressedEntries)
.anyMatch(entry -> entry.contains("reactor.core.publisher.FluxOnAssembly$OnAssemblyException"));
}
}

View File

@ -7,6 +7,11 @@ import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec;
import com.baeldung.debugging.consumer.service.FooService;
/**
* In order to run this live test, start the following classes:
* - com.baeldung.debugging.server.ServerDebuggingApplication
* - com.baeldung.debugging.consumer.ConsumerDebuggingApplication
*/
public class ConsumerFooServiceLiveTest {
FooService service = new FooService();