added files for BidiMapUnitTest
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
### Relevant articles
|
||||
|
||||
- [Introduction to Asciidoctor](http://www.baeldung.com/introduction-to-asciidoctor)
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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">
|
||||
<parent>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>asciidoctor</artifactId>
|
||||
<name>asciidoctor</name>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
<version>1.5.5</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctorj-pdf</artifactId>
|
||||
<version>1.5.0-alpha.15</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>output-pdf</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>process-asciidoc</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<sourceDirectory>src/docs/asciidoc</sourceDirectory>
|
||||
<outputDirectory>target/docs/asciidoc</outputDirectory>
|
||||
<backend>pdf</backend>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctorj</artifactId>
|
||||
<version>1.5.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctorj-pdf</artifactId>
|
||||
<version>1.5.0-alpha.11</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,15 @@
|
||||
Example for the Article on Camel API with SpringBoot
|
||||
|
||||
to start up, run:
|
||||
mvn spring-boot:run
|
||||
|
||||
them, do a POST http request to:
|
||||
http://localhost:8080/camel/api/bean
|
||||
|
||||
with the HEADER: Content-Type: application/json,
|
||||
|
||||
and a BODY Payload like {"id": 1,"name": "World"}
|
||||
|
||||
and we will get a return code of 201 and the response: Hello, World - if the transform() method from Application class is uncommented and the process() method is commented
|
||||
|
||||
or return code of 201 and the response: {"id": 10,"name": "Hello, World"} - if the transform() method from Application class is commented and the process() method is uncommented
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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.example</groupId>
|
||||
<artifactId>spring-boot-camel</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<name>Spring-Boot - Camel API</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||
<camel.version>2.19.1</camel.version>
|
||||
<spring-boot-starter.version>1.5.4.RELEASE</spring-boot-starter.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-servlet-starter</artifactId>
|
||||
<version>${camel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-jackson-starter</artifactId>
|
||||
<version>${camel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-swagger-java-starter</artifactId>
|
||||
<version>${camel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-spring-boot-starter</artifactId>
|
||||
<version>${camel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<defaultGoal>spring-boot:run</defaultGoal>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot-starter.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.baeldung.camel;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.camel.CamelContext;
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Processor;
|
||||
import org.apache.camel.builder.RouteBuilder;
|
||||
import org.apache.camel.component.servlet.CamelHttpTransportServlet;
|
||||
import org.apache.camel.impl.DefaultCamelContext;
|
||||
import org.apache.camel.model.rest.RestBindingMode;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackages="com.baeldung.camel")
|
||||
public class Application extends SpringBootServletInitializer {
|
||||
|
||||
@Value("${server.port}")
|
||||
String serverPort;
|
||||
|
||||
@Value("${baeldung.api.path}")
|
||||
String contextPath;
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ServletRegistrationBean servletRegistrationBean() {
|
||||
ServletRegistrationBean servlet = new ServletRegistrationBean(new CamelHttpTransportServlet(), contextPath+"/*");
|
||||
servlet.setName("CamelServlet");
|
||||
return servlet;
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
class RestApi extends RouteBuilder {
|
||||
|
||||
@Override
|
||||
public void configure() {
|
||||
|
||||
CamelContext context = new DefaultCamelContext();
|
||||
|
||||
|
||||
// http://localhost:8080/camel/api-doc
|
||||
restConfiguration().contextPath(contextPath) //
|
||||
.port(serverPort)
|
||||
.enableCORS(true)
|
||||
.apiContextPath("/api-doc")
|
||||
.apiProperty("api.title", "Test REST API")
|
||||
.apiProperty("api.version", "v1")
|
||||
.apiProperty("cors", "true") // cross-site
|
||||
.apiContextRouteId("doc-api")
|
||||
.component("servlet")
|
||||
.bindingMode(RestBindingMode.json)
|
||||
.dataFormatProperty("prettyPrint", "true");
|
||||
/**
|
||||
The Rest DSL supports automatic binding json/xml contents to/from POJOs using Camels Data Format.
|
||||
By default the binding mode is off, meaning there is no automatic binding happening for incoming and outgoing messages.
|
||||
You may want to use binding if you develop POJOs that maps to your REST services request and response types.
|
||||
This allows you, as a developer, to work with the POJOs in Java code.
|
||||
*/
|
||||
|
||||
rest("/api/").description("Teste REST Service")
|
||||
.id("api-route")
|
||||
.post("/bean")
|
||||
.produces(MediaType.APPLICATION_JSON)
|
||||
.consumes(MediaType.APPLICATION_JSON)
|
||||
// .get("/hello/{place}")
|
||||
.bindingMode(RestBindingMode.auto)
|
||||
.type(MyBean.class)
|
||||
.enableCORS(true)
|
||||
// .outType(OutBean.class)
|
||||
|
||||
.to("direct:remoteService");
|
||||
|
||||
|
||||
from("direct:remoteService")
|
||||
.routeId("direct-route")
|
||||
.tracing()
|
||||
.log(">>> ${body.id}")
|
||||
.log(">>> ${body.name}")
|
||||
// .transform().simple("blue ${in.body.name}")
|
||||
.process(new Processor() {
|
||||
@Override
|
||||
public void process(Exchange exchange) throws Exception {
|
||||
MyBean bodyIn = (MyBean) exchange.getIn().getBody();
|
||||
|
||||
ExampleServices.example(bodyIn);
|
||||
|
||||
exchange.getIn().setBody(bodyIn);
|
||||
}
|
||||
})
|
||||
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(201));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.camel;
|
||||
|
||||
/**
|
||||
* a Mock class to show how some other layer
|
||||
* (a persistence layer, for instance)
|
||||
* could be used insida a Camel
|
||||
*
|
||||
*/
|
||||
public class ExampleServices {
|
||||
|
||||
public static void example(MyBean bodyIn) {
|
||||
bodyIn.setName( "Hello, " + bodyIn.getName() );
|
||||
bodyIn.setId(bodyIn.getId()*10);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.camel;
|
||||
|
||||
public class MyBean {
|
||||
private Integer id;
|
||||
private String name;
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
logging.config=classpath:logback.xml
|
||||
|
||||
# the options from org.apache.camel.spring.boot.CamelConfigurationProperties can be configured here
|
||||
camel.springboot.name=MyCamel
|
||||
|
||||
# lets listen on all ports to ensure we can be invoked from the pod IP
|
||||
server.address=0.0.0.0
|
||||
management.address=0.0.0.0
|
||||
|
||||
# lets use a different management port in case you need to listen to HTTP requests on 8080
|
||||
management.port=8081
|
||||
|
||||
# disable all management enpoints except health
|
||||
endpoints.enabled = true
|
||||
endpoints.health.enabled = true
|
||||
@@ -0,0 +1,27 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
# for example purposes of Camel version 2.18 and below
|
||||
baeldung:
|
||||
api:
|
||||
path: '/camel'
|
||||
|
||||
camel:
|
||||
springboot:
|
||||
# The Camel context name
|
||||
name: ServicesRest
|
||||
|
||||
# Binding health checks to a different port
|
||||
management:
|
||||
port: 8081
|
||||
|
||||
# disable all management enpoints except health
|
||||
endpoints:
|
||||
enabled: false
|
||||
health:
|
||||
enabled: true
|
||||
|
||||
# The application configuration properties
|
||||
quickstart:
|
||||
generateOrderPeriod: 10s
|
||||
processOrderPeriod: 30s
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<configuration>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!-- encoders are assigned the type
|
||||
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
@@ -327,6 +327,22 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<mainClass>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</mainClass>
|
||||
<arguments>
|
||||
<argument>-Xmx300m</argument>
|
||||
<argument>-XX:+UseParallelGC</argument>
|
||||
<argument>-classpath</argument>
|
||||
<classpath/>
|
||||
<argument>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
|
||||
@@ -6,7 +6,7 @@ public class NumbersConsumer implements Runnable {
|
||||
private final BlockingQueue<Integer> queue;
|
||||
private final int poisonPill;
|
||||
|
||||
public NumbersConsumer(BlockingQueue<Integer> queue, int poisonPill) {
|
||||
NumbersConsumer(BlockingQueue<Integer> queue, int poisonPill) {
|
||||
this.queue = queue;
|
||||
this.poisonPill = poisonPill;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ public class NumbersProducer implements Runnable {
|
||||
private final int poisonPill;
|
||||
private final int poisonPillPerProducer;
|
||||
|
||||
public NumbersProducer(BlockingQueue<Integer> numbersQueue, int poisonPill, int poisonPillPerProducer) {
|
||||
NumbersProducer(BlockingQueue<Integer> numbersQueue, int poisonPill, int poisonPillPerProducer) {
|
||||
this.numbersQueue = numbersQueue;
|
||||
this.poisonPill = poisonPill;
|
||||
this.poisonPillPerProducer = poisonPillPerProducer;
|
||||
|
||||
@@ -7,7 +7,7 @@ public class BrokenWorker implements Runnable {
|
||||
private final List<String> outputScraper;
|
||||
private final CountDownLatch countDownLatch;
|
||||
|
||||
public BrokenWorker(final List<String> outputScraper, final CountDownLatch countDownLatch) {
|
||||
BrokenWorker(final List<String> outputScraper, final CountDownLatch countDownLatch) {
|
||||
this.outputScraper = outputScraper;
|
||||
this.countDownLatch = countDownLatch;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public class WaitingWorker implements Runnable {
|
||||
private final CountDownLatch callingThreadBlocker;
|
||||
private final CountDownLatch completedThreadCounter;
|
||||
|
||||
public WaitingWorker(final List<String> outputScraper, final CountDownLatch readyThreadCounter, final CountDownLatch callingThreadBlocker, CountDownLatch completedThreadCounter) {
|
||||
WaitingWorker(final List<String> outputScraper, final CountDownLatch readyThreadCounter, final CountDownLatch callingThreadBlocker, CountDownLatch completedThreadCounter) {
|
||||
|
||||
this.outputScraper = outputScraper;
|
||||
this.readyThreadCounter = readyThreadCounter;
|
||||
|
||||
@@ -7,7 +7,7 @@ public class Worker implements Runnable {
|
||||
private final List<String> outputScraper;
|
||||
private final CountDownLatch countDownLatch;
|
||||
|
||||
public Worker(final List<String> outputScraper, final CountDownLatch countDownLatch) {
|
||||
Worker(final List<String> outputScraper, final CountDownLatch countDownLatch) {
|
||||
this.outputScraper = outputScraper;
|
||||
this.countDownLatch = countDownLatch;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.baeldung.concurrent.cyclicbarrier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.BrokenBarrierException;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
|
||||
public class CyclicBarrierDemo {
|
||||
|
||||
private CyclicBarrier cyclicBarrier;
|
||||
private List<List<Integer>> partialResults = Collections.synchronizedList(new ArrayList<>());
|
||||
private Random random = new Random();
|
||||
private int NUM_PARTIAL_RESULTS;
|
||||
private int NUM_WORKERS;
|
||||
|
||||
|
||||
private void runSimulation(int numWorkers, int numberOfPartialResults) {
|
||||
NUM_PARTIAL_RESULTS = numberOfPartialResults;
|
||||
NUM_WORKERS = numWorkers;
|
||||
|
||||
cyclicBarrier = new CyclicBarrier(NUM_WORKERS, new AggregatorThread());
|
||||
System.out.println("Spawning " + NUM_WORKERS + " worker threads to compute "
|
||||
+ NUM_PARTIAL_RESULTS + " partial results each");
|
||||
for (int i = 0; i < NUM_WORKERS; i++) {
|
||||
Thread worker = new Thread(new NumberCruncherThread());
|
||||
worker.setName("Thread " + i);
|
||||
worker.start();
|
||||
}
|
||||
}
|
||||
|
||||
class NumberCruncherThread implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String thisThreadName = Thread.currentThread().getName();
|
||||
List<Integer> partialResult = new ArrayList<>();
|
||||
for (int i = 0; i < NUM_PARTIAL_RESULTS; i++) {
|
||||
Integer num = random.nextInt(10);
|
||||
System.out.println(thisThreadName
|
||||
+ ": Crunching some numbers! Final result - " + num);
|
||||
partialResult.add(num);
|
||||
}
|
||||
partialResults.add(partialResult);
|
||||
try {
|
||||
System.out.println(thisThreadName + " waiting for others to reach barrier.");
|
||||
cyclicBarrier.await();
|
||||
} catch (InterruptedException | BrokenBarrierException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AggregatorThread implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String thisThreadName = Thread.currentThread().getName();
|
||||
System.out.println(thisThreadName + ": Computing final sum of " + NUM_WORKERS
|
||||
+ " workers, having " + NUM_PARTIAL_RESULTS + " results each.");
|
||||
int sum = 0;
|
||||
for (List<Integer> threadResult : partialResults) {
|
||||
System.out.print("Adding ");
|
||||
for (Integer partialResult : threadResult) {
|
||||
System.out.print(partialResult+" ");
|
||||
sum += partialResult;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println(Thread.currentThread().getName() + ": Final result = " + sum);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
CyclicBarrierDemo play = new CyclicBarrierDemo();
|
||||
play.runSimulation(5, 3);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,7 +9,7 @@ public class DelayObject implements Delayed {
|
||||
private String data;
|
||||
private long startTime;
|
||||
|
||||
public DelayObject(String data, long delayInMilliseconds) {
|
||||
DelayObject(String data, long delayInMilliseconds) {
|
||||
this.data = data;
|
||||
this.startTime = System.currentTimeMillis() + delayInMilliseconds;
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
public class DelayQueueConsumer implements Runnable {
|
||||
private BlockingQueue<DelayObject> queue;
|
||||
private final Integer numberOfElementsToTake;
|
||||
public final AtomicInteger numberOfConsumedElements = new AtomicInteger();
|
||||
final AtomicInteger numberOfConsumedElements = new AtomicInteger();
|
||||
|
||||
public DelayQueueConsumer(BlockingQueue<DelayObject> queue, Integer numberOfElementsToTake) {
|
||||
DelayQueueConsumer(BlockingQueue<DelayObject> queue, Integer numberOfElementsToTake) {
|
||||
this.queue = queue;
|
||||
this.numberOfElementsToTake = numberOfElementsToTake;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ public class DelayQueueProducer implements Runnable {
|
||||
private final Integer numberOfElementsToProduce;
|
||||
private final Integer delayOfEachProducedMessageMilliseconds;
|
||||
|
||||
public DelayQueueProducer(BlockingQueue<DelayObject> queue,
|
||||
Integer numberOfElementsToProduce,
|
||||
Integer delayOfEachProducedMessageMilliseconds) {
|
||||
DelayQueueProducer(BlockingQueue<DelayObject> queue,
|
||||
Integer numberOfElementsToProduce,
|
||||
Integer delayOfEachProducedMessageMilliseconds) {
|
||||
this.queue = queue;
|
||||
this.numberOfElementsToProduce = numberOfElementsToProduce;
|
||||
this.delayOfEachProducedMessageMilliseconds = delayOfEachProducedMessageMilliseconds;
|
||||
|
||||
@@ -5,7 +5,7 @@ public class Philosopher implements Runnable {
|
||||
private final Object leftFork;
|
||||
private final Object rightFork;
|
||||
|
||||
public Philosopher(Object left, Object right) {
|
||||
Philosopher(Object left, Object right) {
|
||||
this.leftFork = left;
|
||||
this.rightFork = right;
|
||||
}
|
||||
@@ -30,7 +30,6 @@ public class Philosopher implements Runnable {
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,7 +7,7 @@ public class FactorialSquareCalculator extends RecursiveTask<Integer> {
|
||||
|
||||
final private Integer n;
|
||||
|
||||
public FactorialSquareCalculator(Integer n) {
|
||||
FactorialSquareCalculator(Integer n) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,15 +3,15 @@ package com.baeldung.concurrent.future;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class SquareCalculator {
|
||||
class SquareCalculator {
|
||||
|
||||
private final ExecutorService executor;
|
||||
|
||||
public SquareCalculator(ExecutorService executor) {
|
||||
SquareCalculator(ExecutorService executor) {
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public Future<Integer> calculate(Integer input) {
|
||||
Future<Integer> calculate(Integer input) {
|
||||
return executor.submit(() -> {
|
||||
Thread.sleep(1000);
|
||||
return input * input;
|
||||
|
||||
+57
-57
@@ -13,71 +13,71 @@ import static java.lang.Thread.sleep;
|
||||
|
||||
public class ReentrantLockWithCondition {
|
||||
|
||||
static Logger logger = LoggerFactory.getLogger(ReentrantLockWithCondition.class);
|
||||
private static Logger LOG = LoggerFactory.getLogger(ReentrantLockWithCondition.class);
|
||||
|
||||
Stack<String> stack = new Stack<>();
|
||||
int CAPACITY = 5;
|
||||
private Stack<String> stack = new Stack<>();
|
||||
private static final int CAPACITY = 5;
|
||||
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
Condition stackEmptyCondition = lock.newCondition();
|
||||
Condition stackFullCondition = lock.newCondition();
|
||||
private ReentrantLock lock = new ReentrantLock();
|
||||
private Condition stackEmptyCondition = lock.newCondition();
|
||||
private Condition stackFullCondition = lock.newCondition();
|
||||
|
||||
public void pushToStack(String item) throws InterruptedException {
|
||||
try {
|
||||
lock.lock();
|
||||
if (stack.size() == CAPACITY) {
|
||||
logger.info(Thread.currentThread().getName() + " wait on stack full");
|
||||
stackFullCondition.await();
|
||||
}
|
||||
logger.info("Pushing the item " + item);
|
||||
stack.push(item);
|
||||
stackEmptyCondition.signalAll();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
private void pushToStack(String item) throws InterruptedException {
|
||||
try {
|
||||
lock.lock();
|
||||
if (stack.size() == CAPACITY) {
|
||||
LOG.info(Thread.currentThread().getName() + " wait on stack full");
|
||||
stackFullCondition.await();
|
||||
}
|
||||
LOG.info("Pushing the item " + item);
|
||||
stack.push(item);
|
||||
stackEmptyCondition.signalAll();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public String popFromStack() throws InterruptedException {
|
||||
try {
|
||||
lock.lock();
|
||||
if (stack.size() == 0) {
|
||||
logger.info(Thread.currentThread().getName() + " wait on stack empty");
|
||||
stackEmptyCondition.await();
|
||||
}
|
||||
return stack.pop();
|
||||
} finally {
|
||||
stackFullCondition.signalAll();
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
private String popFromStack() throws InterruptedException {
|
||||
try {
|
||||
lock.lock();
|
||||
if (stack.size() == 0) {
|
||||
LOG.info(Thread.currentThread().getName() + " wait on stack empty");
|
||||
stackEmptyCondition.await();
|
||||
}
|
||||
return stack.pop();
|
||||
} finally {
|
||||
stackFullCondition.signalAll();
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final int threadCount = 2;
|
||||
ReentrantLockWithCondition object = new ReentrantLockWithCondition();
|
||||
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||
service.execute(() -> {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
try {
|
||||
object.pushToStack("Item " + i);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
final int threadCount = 2;
|
||||
ReentrantLockWithCondition object = new ReentrantLockWithCondition();
|
||||
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||
service.execute(() -> {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
try {
|
||||
object.pushToStack("Item " + i);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
service.execute(() -> {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
try {
|
||||
logger.info("Item popped " + object.popFromStack());
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
service.execute(() -> {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
try {
|
||||
LOG.info("Item popped " + object.popFromStack());
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
service.shutdown();
|
||||
}
|
||||
service.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,81 +12,77 @@ import static java.lang.Thread.sleep;
|
||||
|
||||
public class SharedObjectWithLock {
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(SharedObjectWithLock.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SharedObjectWithLock.class);
|
||||
|
||||
ReentrantLock lock = new ReentrantLock(true);
|
||||
private ReentrantLock lock = new ReentrantLock(true);
|
||||
|
||||
int counter = 0;
|
||||
private int counter = 0;
|
||||
|
||||
public void perform() {
|
||||
void perform() {
|
||||
|
||||
lock.lock();
|
||||
logger.info("Thread - " + Thread.currentThread().getName() + " acquired the lock");
|
||||
try {
|
||||
logger.info("Thread - " + Thread.currentThread().getName() + " processing");
|
||||
counter++;
|
||||
} catch (Exception exception) {
|
||||
logger.error(" Interrupted Exception ", exception);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
logger.info("Thread - " + Thread.currentThread().getName() + " released the lock");
|
||||
}
|
||||
}
|
||||
lock.lock();
|
||||
LOG.info("Thread - " + Thread.currentThread().getName() + " acquired the lock");
|
||||
try {
|
||||
LOG.info("Thread - " + Thread.currentThread().getName() + " processing");
|
||||
counter++;
|
||||
} catch (Exception exception) {
|
||||
LOG.error(" Interrupted Exception ", exception);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
LOG.info("Thread - " + Thread.currentThread().getName() + " released the lock");
|
||||
}
|
||||
}
|
||||
|
||||
public void performTryLock() {
|
||||
private void performTryLock() {
|
||||
|
||||
logger.info("Thread - " + Thread.currentThread().getName() + " attempting to acquire the lock");
|
||||
try {
|
||||
boolean isLockAcquired = lock.tryLock(2, TimeUnit.SECONDS);
|
||||
if (isLockAcquired) {
|
||||
try {
|
||||
logger.info("Thread - " + Thread.currentThread().getName() + " acquired the lock");
|
||||
LOG.info("Thread - " + Thread.currentThread().getName() + " attempting to acquire the lock");
|
||||
try {
|
||||
boolean isLockAcquired = lock.tryLock(2, TimeUnit.SECONDS);
|
||||
if (isLockAcquired) {
|
||||
try {
|
||||
LOG.info("Thread - " + Thread.currentThread().getName() + " acquired the lock");
|
||||
|
||||
logger.info("Thread - " + Thread.currentThread().getName() + " processing");
|
||||
sleep(1000);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
logger.info("Thread - " + Thread.currentThread().getName() + " released the lock");
|
||||
LOG.info("Thread - " + Thread.currentThread().getName() + " processing");
|
||||
sleep(1000);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
LOG.info("Thread - " + Thread.currentThread().getName() + " released the lock");
|
||||
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException exception) {
|
||||
logger.error(" Interrupted Exception ", exception);
|
||||
}
|
||||
logger.info("Thread - " + Thread.currentThread().getName() + " could not acquire the lock");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException exception) {
|
||||
LOG.error(" Interrupted Exception ", exception);
|
||||
}
|
||||
LOG.info("Thread - " + Thread.currentThread().getName() + " could not acquire the lock");
|
||||
}
|
||||
|
||||
public ReentrantLock getLock() {
|
||||
return lock;
|
||||
}
|
||||
public ReentrantLock getLock() {
|
||||
return lock;
|
||||
}
|
||||
|
||||
boolean isLocked() {
|
||||
return lock.isLocked();
|
||||
}
|
||||
boolean isLocked() {
|
||||
return lock.isLocked();
|
||||
}
|
||||
|
||||
boolean hasQueuedThreads() {
|
||||
return lock.hasQueuedThreads();
|
||||
}
|
||||
boolean hasQueuedThreads() {
|
||||
return lock.hasQueuedThreads();
|
||||
}
|
||||
|
||||
int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) {
|
||||
|
||||
final int threadCount = 2;
|
||||
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||
final SharedObjectWithLock object = new SharedObjectWithLock();
|
||||
final int threadCount = 2;
|
||||
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||
final SharedObjectWithLock object = new SharedObjectWithLock();
|
||||
|
||||
service.execute(() -> {
|
||||
object.perform();
|
||||
});
|
||||
service.execute(() -> {
|
||||
object.performTryLock();
|
||||
});
|
||||
service.execute(object::perform);
|
||||
service.execute(object::performTryLock);
|
||||
|
||||
service.shutdown();
|
||||
service.shutdown();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,93 +12,93 @@ import java.util.concurrent.locks.StampedLock;
|
||||
import static java.lang.Thread.sleep;
|
||||
|
||||
public class StampedLockDemo {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
Logger logger = LoggerFactory.getLogger(StampedLockDemo.class);
|
||||
private Map<String, String> map = new HashMap<>();
|
||||
private Logger logger = LoggerFactory.getLogger(StampedLockDemo.class);
|
||||
|
||||
private final StampedLock lock = new StampedLock();
|
||||
private final StampedLock lock = new StampedLock();
|
||||
|
||||
public void put(String key, String value) throws InterruptedException {
|
||||
long stamp = lock.writeLock();
|
||||
public void put(String key, String value) throws InterruptedException {
|
||||
long stamp = lock.writeLock();
|
||||
|
||||
try {
|
||||
logger.info(Thread.currentThread().getName() + " acquired the write lock with stamp " + stamp);
|
||||
map.put(key, value);
|
||||
} finally {
|
||||
lock.unlockWrite(stamp);
|
||||
logger.info(Thread.currentThread().getName() + " unlocked the write lock with stamp " + stamp);
|
||||
}
|
||||
}
|
||||
try {
|
||||
logger.info(Thread.currentThread().getName() + " acquired the write lock with stamp " + stamp);
|
||||
map.put(key, value);
|
||||
} finally {
|
||||
lock.unlockWrite(stamp);
|
||||
logger.info(Thread.currentThread().getName() + " unlocked the write lock with stamp " + stamp);
|
||||
}
|
||||
}
|
||||
|
||||
public String get(String key) throws InterruptedException {
|
||||
long stamp = lock.readLock();
|
||||
logger.info(Thread.currentThread().getName() + " acquired the read lock with stamp " + stamp);
|
||||
try {
|
||||
sleep(5000);
|
||||
return map.get(key);
|
||||
public String get(String key) throws InterruptedException {
|
||||
long stamp = lock.readLock();
|
||||
logger.info(Thread.currentThread().getName() + " acquired the read lock with stamp " + stamp);
|
||||
try {
|
||||
sleep(5000);
|
||||
return map.get(key);
|
||||
|
||||
} finally {
|
||||
lock.unlockRead(stamp);
|
||||
logger.info(Thread.currentThread().getName() + " unlocked the read lock with stamp " + stamp);
|
||||
} finally {
|
||||
lock.unlockRead(stamp);
|
||||
logger.info(Thread.currentThread().getName() + " unlocked the read lock with stamp " + stamp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public String readWithOptimisticLock(String key) throws InterruptedException {
|
||||
long stamp = lock.tryOptimisticRead();
|
||||
String value = map.get(key);
|
||||
private String readWithOptimisticLock(String key) throws InterruptedException {
|
||||
long stamp = lock.tryOptimisticRead();
|
||||
String value = map.get(key);
|
||||
|
||||
if (!lock.validate(stamp)) {
|
||||
stamp = lock.readLock();
|
||||
try {
|
||||
sleep(5000);
|
||||
return map.get(key);
|
||||
if (!lock.validate(stamp)) {
|
||||
stamp = lock.readLock();
|
||||
try {
|
||||
sleep(5000);
|
||||
return map.get(key);
|
||||
|
||||
} finally {
|
||||
lock.unlock(stamp);
|
||||
logger.info(Thread.currentThread().getName() + " unlocked the read lock with stamp " + stamp);
|
||||
} finally {
|
||||
lock.unlock(stamp);
|
||||
logger.info(Thread.currentThread().getName() + " unlocked the read lock with stamp " + stamp);
|
||||
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final int threadCount = 4;
|
||||
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||
StampedLockDemo object = new StampedLockDemo();
|
||||
public static void main(String[] args) {
|
||||
final int threadCount = 4;
|
||||
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||
StampedLockDemo object = new StampedLockDemo();
|
||||
|
||||
Runnable writeTask = () -> {
|
||||
Runnable writeTask = () -> {
|
||||
|
||||
try {
|
||||
object.put("key1", "value1");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
Runnable readTask = () -> {
|
||||
try {
|
||||
object.put("key1", "value1");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
Runnable readTask = () -> {
|
||||
|
||||
try {
|
||||
object.get("key1");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
Runnable readOptimisticTask = () -> {
|
||||
try {
|
||||
object.get("key1");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
Runnable readOptimisticTask = () -> {
|
||||
|
||||
try {
|
||||
object.readWithOptimisticLock("key1");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
service.submit(writeTask);
|
||||
service.submit(writeTask);
|
||||
service.submit(readTask);
|
||||
service.submit(readOptimisticTask);
|
||||
try {
|
||||
object.readWithOptimisticLock("key1");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
service.submit(writeTask);
|
||||
service.submit(writeTask);
|
||||
service.submit(readTask);
|
||||
service.submit(readOptimisticTask);
|
||||
|
||||
service.shutdown();
|
||||
service.shutdown();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user