diff --git a/core-java-modules/core-java-concurrency-testing/.gitignore b/core-java-modules/core-java-concurrency-testing/.gitignore
new file mode 100644
index 0000000000..3de4cc647e
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/.gitignore
@@ -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
\ No newline at end of file
diff --git a/core-java-modules/core-java-concurrency-testing/README.md b/core-java-modules/core-java-concurrency-testing/README.md
new file mode 100644
index 0000000000..fef74a6750
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/README.md
@@ -0,0 +1,7 @@
+=========
+
+## Core Java Concurrency Testing Examples
+
+### Relevant Articles:
+- [Testing Multi-Threaded Code in Java](https://www.baeldung.com/java-testing-multithreaded)
+
diff --git a/core-java-modules/core-java-concurrency-testing/pom.xml b/core-java-modules/core-java-concurrency-testing/pom.xml
new file mode 100644
index 0000000000..bb3e6f5152
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/pom.xml
@@ -0,0 +1,93 @@
+
+
+ 4.0.0
+ core-java-concurrency-testing
+ 0.1.0-SNAPSHOT
+ core-java-concurrency-testing
+ jar
+
+
+ com.baeldung
+ parent-java
+ 0.0.1-SNAPSHOT
+ ../../parent-java
+
+
+
+
+ junit
+ junit
+ 4.13
+ test
+
+
+ com.googlecode.thread-weaver
+ threadweaver
+ 0.2
+ test
+
+
+ com.google.code.tempus-fugit
+ tempus-fugit
+ 1.1
+ test
+
+
+ com.googlecode.multithreadedtc
+ multithreadedtc
+ 1.01
+ test
+
+
+ org.openjdk.jcstress
+ jcstress-core
+ 0.5
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ ${javac.target}
+ ${javac.target}
+ ${javac.target}
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.2
+
+
+ main
+ package
+
+ shade
+
+
+ jcstress
+
+
+ org.openjdk.jcstress.Main
+
+
+ META-INF/TestList
+
+
+
+
+
+
+
+
+
+
diff --git a/core-java-modules/core-java-concurrency-testing/src/main/java/com/baeldung/concurrent/MyCounter.java b/core-java-modules/core-java-concurrency-testing/src/main/java/com/baeldung/concurrent/MyCounter.java
new file mode 100644
index 0000000000..a678b047a8
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/src/main/java/com/baeldung/concurrent/MyCounter.java
@@ -0,0 +1,22 @@
+package com.baeldung.concurrent;
+
+public class MyCounter {
+
+ private int count;
+
+ public void increment() {
+ int temp = count;
+ count = temp + 1;
+ }
+
+ public synchronized void incrementWithWait() throws InterruptedException {
+ int temp = count;
+ wait(100);
+ count = temp + 1;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+}
diff --git a/core-java-modules/core-java-concurrency-testing/src/main/resources/logback.xml b/core-java-modules/core-java-concurrency-testing/src/main/resources/logback.xml
new file mode 100644
index 0000000000..56af2d397e
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/src/main/resources/logback.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterJCStressUnitTest.java b/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterJCStressUnitTest.java
new file mode 100644
index 0000000000..6c76505347
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterJCStressUnitTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.concurrent;
+
+import static org.openjdk.jcstress.annotations.Expect.ACCEPTABLE;
+import static org.openjdk.jcstress.annotations.Expect.ACCEPTABLE_INTERESTING;
+
+import org.openjdk.jcstress.annotations.Actor;
+import org.openjdk.jcstress.annotations.Arbiter;
+import org.openjdk.jcstress.annotations.JCStressTest;
+import org.openjdk.jcstress.annotations.Outcome;
+import org.openjdk.jcstress.annotations.State;
+import org.openjdk.jcstress.infra.results.I_Result;
+
+@JCStressTest
+@Outcome(id = "1", expect = ACCEPTABLE_INTERESTING, desc = "One update lost.")
+@Outcome(id = "2", expect = ACCEPTABLE, desc = "Both updates.")
+@State
+public class MyCounterJCStressUnitTest {
+
+ private MyCounter counter;
+
+ @Actor
+ public void actor1() {
+ counter.increment();
+ }
+
+ @Actor
+ public void actor2() {
+ counter.increment();
+ }
+
+ @Arbiter
+ public void arbiter(I_Result r) {
+ r.r1 = counter.getCount();
+ }
+
+}
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java b/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java
new file mode 100644
index 0000000000..eb4e77cae9
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java
@@ -0,0 +1,35 @@
+package com.baeldung.concurrent;
+
+import org.junit.Test;
+
+import edu.umd.cs.mtc.MultithreadedTestCase;
+import edu.umd.cs.mtc.TestFramework;
+
+public class MyCounterMultithreadedTCUnitTest extends MultithreadedTestCase {
+
+ private MyCounter counter;
+
+ @Override
+ public void initialize() {
+ counter = new MyCounter();
+ }
+
+ public void thread1() throws InterruptedException {
+ counter.increment();
+ }
+
+ public void thread2() throws InterruptedException {
+ counter.increment();
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void finish() {
+ assertEquals(2, counter.getCount());
+ }
+
+ @Test
+ public void testCounter() throws Throwable {
+ TestFramework.runManyTimes(new MyCounterMultithreadedTCUnitTest(), 1000);
+ }
+}
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java b/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java
new file mode 100644
index 0000000000..4f3409b923
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java
@@ -0,0 +1,57 @@
+package com.baeldung.concurrent;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.junit.Test;
+
+public class MyCounterSimpleUnitTest {
+
+ @Test
+ public void testCounter() {
+ MyCounter counter = new MyCounter();
+ for (int i = 0; i < 500; i++)
+ counter.increment();
+ assertEquals(500, counter.getCount());
+ }
+
+ // @Test
+ public void testCounterWithConcurrency() throws InterruptedException {
+ int numberOfThreads = 100;
+ ExecutorService service = Executors.newFixedThreadPool(10);
+ CountDownLatch latch = new CountDownLatch(numberOfThreads);
+ MyCounter counter = new MyCounter();
+ for (int i = 0; i < numberOfThreads; i++) {
+ service.execute(() -> {
+ counter.increment();
+ latch.countDown();
+ });
+ }
+ latch.await();
+ assertEquals(numberOfThreads, counter.getCount());
+ }
+
+ // @Test
+ public void testSummationWithConcurrencyAndWait() throws InterruptedException {
+ int numberOfThreads = 2;
+ ExecutorService service = Executors.newFixedThreadPool(10);
+ CountDownLatch latch = new CountDownLatch(numberOfThreads);
+ MyCounter counter = new MyCounter();
+ for (int i = 0; i < numberOfThreads; i++) {
+ service.submit(() -> {
+ try {
+ counter.incrementWithWait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ latch.countDown();
+ });
+ }
+ latch.await();
+ assertEquals(numberOfThreads, counter.getCount());
+ }
+
+}
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java b/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java
new file mode 100644
index 0000000000..360c61b4f4
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java
@@ -0,0 +1,35 @@
+package com.baeldung.concurrent;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.AfterClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.code.tempusfugit.concurrency.ConcurrentRule;
+import com.google.code.tempusfugit.concurrency.RepeatingRule;
+import com.google.code.tempusfugit.concurrency.annotations.Concurrent;
+import com.google.code.tempusfugit.concurrency.annotations.Repeating;
+
+public class MyCounterTempusFugitUnitTest {
+
+ @Rule
+ public ConcurrentRule concurrently = new ConcurrentRule();
+ @Rule
+ public RepeatingRule rule = new RepeatingRule();
+
+ private static MyCounter counter = new MyCounter();
+
+ @Test
+ @Concurrent(count = 2)
+ @Repeating(repetition = 10)
+ public void runsMultipleTimes() {
+ counter.increment();
+ }
+
+ @AfterClass
+ public static void annotatedTestRunsMultipleTimes() throws InterruptedException {
+ assertEquals(counter.getCount(), 20);
+ }
+
+}
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java b/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java
new file mode 100644
index 0000000000..29b08996cd
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java
@@ -0,0 +1,42 @@
+package com.baeldung.concurrent;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.google.testing.threadtester.AnnotatedTestRunner;
+import com.google.testing.threadtester.ThreadedAfter;
+import com.google.testing.threadtester.ThreadedBefore;
+import com.google.testing.threadtester.ThreadedMain;
+import com.google.testing.threadtester.ThreadedSecondary;
+
+public class MyCounterThreadWeaverUnitTest {
+
+ private MyCounter counter;
+
+ @ThreadedBefore
+ public void before() {
+ counter = new MyCounter();
+ }
+
+ @ThreadedMain
+ public void mainThread() {
+ counter.increment();
+ }
+
+ @ThreadedSecondary
+ public void secondThread() {
+ counter.increment();
+ }
+
+ @ThreadedAfter
+ public void after() {
+ assertEquals(2, counter.getCount());
+ }
+
+ @Test
+ public void testCounter() {
+ new AnnotatedTestRunner().runTests(this.getClass(), MyCounter.class);
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/resources/.gitignore b/core-java-modules/core-java-concurrency-testing/src/test/resources/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-testing/src/test/resources/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file