[BAEL-10837] - Splitted core-java-concurrency module
This commit is contained in:
parent
8fbed2e741
commit
45ba2a9387
@ -1,33 +1,21 @@
|
|||||||
=========
|
=========
|
||||||
|
|
||||||
## Core Java Concurrency Examples
|
## Core Java Concurrency Advanced Examples
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Guide To CompletableFuture](http://www.baeldung.com/java-completablefuture)
|
|
||||||
- [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial)
|
|
||||||
- [Introduction to Thread Pools in Java](http://www.baeldung.com/thread-pool-java-and-guava)
|
- [Introduction to Thread Pools in Java](http://www.baeldung.com/thread-pool-java-and-guava)
|
||||||
- [Guide to java.util.concurrent.Future](http://www.baeldung.com/java-future)
|
|
||||||
- [Guide to CountDownLatch in Java](http://www.baeldung.com/java-countdown-latch)
|
- [Guide to CountDownLatch in Java](http://www.baeldung.com/java-countdown-latch)
|
||||||
- [Guide to java.util.concurrent.Locks](http://www.baeldung.com/java-concurrent-locks)
|
- [Guide to java.util.concurrent.Locks](http://www.baeldung.com/java-concurrent-locks)
|
||||||
- [An Introduction to ThreadLocal in Java](http://www.baeldung.com/java-threadlocal)
|
- [An Introduction to ThreadLocal in Java](http://www.baeldung.com/java-threadlocal)
|
||||||
- [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep)
|
|
||||||
- [LongAdder and LongAccumulator in Java](http://www.baeldung.com/java-longadder-and-longaccumulator)
|
- [LongAdder and LongAccumulator in Java](http://www.baeldung.com/java-longadder-and-longaccumulator)
|
||||||
- [The Dining Philosophers Problem in Java](http://www.baeldung.com/java-dining-philoshophers)
|
- [The Dining Philosophers Problem in Java](http://www.baeldung.com/java-dining-philoshophers)
|
||||||
- [Guide to the Java Phaser](http://www.baeldung.com/java-phaser)
|
- [Guide to the Java Phaser](http://www.baeldung.com/java-phaser)
|
||||||
- [Guide to Synchronized Keyword in Java](http://www.baeldung.com/java-synchronized)
|
|
||||||
- [An Introduction to Atomic Variables in Java](http://www.baeldung.com/java-atomic-variables)
|
- [An Introduction to Atomic Variables in Java](http://www.baeldung.com/java-atomic-variables)
|
||||||
- [CyclicBarrier in Java](http://www.baeldung.com/java-cyclic-barrier)
|
- [CyclicBarrier in Java](http://www.baeldung.com/java-cyclic-barrier)
|
||||||
- [Guide to Volatile Keyword in Java](http://www.baeldung.com/java-volatile)
|
- [Guide to Volatile Keyword in Java](http://www.baeldung.com/java-volatile)
|
||||||
- [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent)
|
|
||||||
- [Semaphores in Java](http://www.baeldung.com/java-semaphore)
|
- [Semaphores in Java](http://www.baeldung.com/java-semaphore)
|
||||||
- [Daemon Threads in Java](http://www.baeldung.com/java-daemon-thread)
|
- [Daemon Threads in Java](http://www.baeldung.com/java-daemon-thread)
|
||||||
- [Implementing a Runnable vs Extending a Thread](http://www.baeldung.com/java-runnable-vs-extending-thread)
|
|
||||||
- [How to Kill a Java Thread](http://www.baeldung.com/java-thread-stop)
|
|
||||||
- [ExecutorService - Waiting for Threads to Finish](http://www.baeldung.com/java-executor-wait-for-threads)
|
|
||||||
- [wait and notify() Methods in Java](http://www.baeldung.com/java-wait-notify)
|
|
||||||
- [Priority-based Job Scheduling in Java](http://www.baeldung.com/java-priority-job-schedule)
|
- [Priority-based Job Scheduling in Java](http://www.baeldung.com/java-priority-job-schedule)
|
||||||
- [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle)
|
|
||||||
- [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable)
|
|
||||||
- [Brief Introduction to Java Thread.yield()](https://www.baeldung.com/java-thread-yield)
|
- [Brief Introduction to Java Thread.yield()](https://www.baeldung.com/java-thread-yield)
|
||||||
- [Print Even and Odd Numbers Using 2 Threads](https://www.baeldung.com/java-even-odd-numbers-with-2-threads)
|
- [Print Even and Odd Numbers Using 2 Threads](https://www.baeldung.com/java-even-odd-numbers-with-2-threads)
|
||||||
- [Java CyclicBarrier vs CountDownLatch](https://www.baeldung.com/java-cyclicbarrier-countdownlatch)
|
- [Java CyclicBarrier vs CountDownLatch](https://www.baeldung.com/java-cyclicbarrier-countdownlatch)
|
@ -2,10 +2,10 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
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</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>core-java-concurrency</artifactId>
|
<artifactId>core-java-concurrency-advanced</artifactId>
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>core-java-concurrency</name>
|
<name>core-java-concurrency-advanced</name>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
@ -60,7 +60,7 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<finalName>core-java-concurrency</finalName>
|
<finalName>core-java-concurrency-advanced</finalName>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>src/main/resources</directory>
|
<directory>src/main/resources</directory>
|
@ -1,13 +1,13 @@
|
|||||||
package com.baeldung.concurrent.atomic;
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
public class SafeCounterWithLock {
|
public class SafeCounterWithLock {
|
||||||
private volatile int counter;
|
private volatile int counter;
|
||||||
|
|
||||||
int getValue() {
|
int getValue() {
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void increment() {
|
synchronized void increment() {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,21 +1,21 @@
|
|||||||
package com.baeldung.concurrent.atomic;
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class SafeCounterWithoutLock {
|
public class SafeCounterWithoutLock {
|
||||||
private final AtomicInteger counter = new AtomicInteger(0);
|
private final AtomicInteger counter = new AtomicInteger(0);
|
||||||
|
|
||||||
int getValue() {
|
int getValue() {
|
||||||
return counter.get();
|
return counter.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void increment() {
|
void increment() {
|
||||||
while(true) {
|
while(true) {
|
||||||
int existingValue = getValue();
|
int existingValue = getValue();
|
||||||
int newValue = existingValue + 1;
|
int newValue = existingValue + 1;
|
||||||
if(counter.compareAndSet(existingValue, newValue)) {
|
if(counter.compareAndSet(existingValue, newValue)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,13 +1,13 @@
|
|||||||
package com.baeldung.concurrent.atomic;
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
public class UnsafeCounter {
|
public class UnsafeCounter {
|
||||||
private int counter;
|
private int counter;
|
||||||
|
|
||||||
int getValue() {
|
int getValue() {
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void increment() {
|
void increment() {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,38 +1,38 @@
|
|||||||
package com.baeldung.concurrent.atomic;
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class ThreadSafeCounterIntegrationTest {
|
public class ThreadSafeCounterIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenMultiThread_whenSafeCounterWithLockIncrement() throws InterruptedException {
|
public void givenMultiThread_whenSafeCounterWithLockIncrement() throws InterruptedException {
|
||||||
ExecutorService service = Executors.newFixedThreadPool(3);
|
ExecutorService service = Executors.newFixedThreadPool(3);
|
||||||
SafeCounterWithLock safeCounter = new SafeCounterWithLock();
|
SafeCounterWithLock safeCounter = new SafeCounterWithLock();
|
||||||
|
|
||||||
IntStream.range(0, 1000)
|
IntStream.range(0, 1000)
|
||||||
.forEach(count -> service.submit(safeCounter::increment));
|
.forEach(count -> service.submit(safeCounter::increment));
|
||||||
service.awaitTermination(100, TimeUnit.MILLISECONDS);
|
service.awaitTermination(100, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
assertEquals(1000, safeCounter.getValue());
|
assertEquals(1000, safeCounter.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenMultiThread_whenSafeCounterWithoutLockIncrement() throws InterruptedException {
|
public void givenMultiThread_whenSafeCounterWithoutLockIncrement() throws InterruptedException {
|
||||||
ExecutorService service = Executors.newFixedThreadPool(3);
|
ExecutorService service = Executors.newFixedThreadPool(3);
|
||||||
SafeCounterWithoutLock safeCounter = new SafeCounterWithoutLock();
|
SafeCounterWithoutLock safeCounter = new SafeCounterWithoutLock();
|
||||||
|
|
||||||
IntStream.range(0, 1000)
|
IntStream.range(0, 1000)
|
||||||
.forEach(count -> service.submit(safeCounter::increment));
|
.forEach(count -> service.submit(safeCounter::increment));
|
||||||
service.awaitTermination(100, TimeUnit.MILLISECONDS);
|
service.awaitTermination(100, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
assertEquals(1000, safeCounter.getValue());
|
assertEquals(1000, safeCounter.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,33 +1,33 @@
|
|||||||
package com.baeldung.concurrent.atomic;
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test shows the behaviour of a thread-unsafe class in a multithreaded scenario. We are calling
|
* This test shows the behaviour of a thread-unsafe class in a multithreaded scenario. We are calling
|
||||||
* the increment methods 1000 times from a pool of 3 threads. In most of the cases, the counter will
|
* the increment methods 1000 times from a pool of 3 threads. In most of the cases, the counter will
|
||||||
* less than 1000, because of lost updates, however, occasionally it may reach 1000, when no threads
|
* less than 1000, because of lost updates, however, occasionally it may reach 1000, when no threads
|
||||||
* called the method simultaneously. This may cause the build to fail occasionally. Hence excluding this
|
* called the method simultaneously. This may cause the build to fail occasionally. Hence excluding this
|
||||||
* test from build by adding this in manual test
|
* test from build by adding this in manual test
|
||||||
*/
|
*/
|
||||||
public class ThreadUnsafeCounterManualTest {
|
public class ThreadUnsafeCounterManualTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenMultiThread_whenUnsafeCounterIncrement() throws InterruptedException {
|
public void givenMultiThread_whenUnsafeCounterIncrement() throws InterruptedException {
|
||||||
ExecutorService service = Executors.newFixedThreadPool(3);
|
ExecutorService service = Executors.newFixedThreadPool(3);
|
||||||
UnsafeCounter unsafeCounter = new UnsafeCounter();
|
UnsafeCounter unsafeCounter = new UnsafeCounter();
|
||||||
|
|
||||||
IntStream.range(0, 1000)
|
IntStream.range(0, 1000)
|
||||||
.forEach(count -> service.submit(unsafeCounter::increment));
|
.forEach(count -> service.submit(unsafeCounter::increment));
|
||||||
service.awaitTermination(100, TimeUnit.MILLISECONDS);
|
service.awaitTermination(100, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
assertEquals(1000, unsafeCounter.getValue());
|
assertEquals(1000, unsafeCounter.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
26
core-java-concurrency-basic/.gitignore
vendored
Normal file
26
core-java-concurrency-basic/.gitignore
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
*.class
|
||||||
|
|
||||||
|
0.*
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
.resourceCache
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
|
||||||
|
# Files generated by integration tests
|
||||||
|
*.txt
|
||||||
|
backup-pom.xml
|
||||||
|
/bin/
|
||||||
|
/temp
|
||||||
|
|
||||||
|
#IntelliJ specific
|
||||||
|
.idea/
|
||||||
|
*.iml
|
17
core-java-concurrency-basic/README.md
Normal file
17
core-java-concurrency-basic/README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
=========
|
||||||
|
|
||||||
|
## Core Java Concurrency Basic Examples
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Guide To CompletableFuture](http://www.baeldung.com/java-completablefuture)
|
||||||
|
- [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial)
|
||||||
|
- [Guide to java.util.concurrent.Future](http://www.baeldung.com/java-future)
|
||||||
|
- [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep)
|
||||||
|
- [Guide to Synchronized Keyword in Java](http://www.baeldung.com/java-synchronized)
|
||||||
|
- [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent)
|
||||||
|
- [Implementing a Runnable vs Extending a Thread](http://www.baeldung.com/java-runnable-vs-extending-thread)
|
||||||
|
- [How to Kill a Java Thread](http://www.baeldung.com/java-thread-stop)
|
||||||
|
- [ExecutorService - Waiting for Threads to Finish](http://www.baeldung.com/java-executor-wait-for-threads)
|
||||||
|
- [wait and notify() Methods in Java](http://www.baeldung.com/java-wait-notify)
|
||||||
|
- [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle)
|
||||||
|
- [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable)
|
55
core-java-concurrency-basic/pom.xml
Normal file
55
core-java-concurrency-basic/pom.xml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<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</groupId>
|
||||||
|
<artifactId>core-java-concurrency-basic</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>core-java-concurrency-basic</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-java</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-java</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jayway.awaitility</groupId>
|
||||||
|
<artifactId>awaitility</artifactId>
|
||||||
|
<version>${avaitility.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>core-java-concurrency-basic</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- util -->
|
||||||
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
|
<!-- testing -->
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
<avaitility.version>1.7.0</avaitility.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user