From c60c8705060224c6f606cb7428747278638e3945 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 18 Jan 2017 22:50:56 +0000 Subject: [PATCH] BAEL-613 --- .../countdownlatch/BrokenWorker.java | 23 +++++++ .../concurrent/countdownlatch/Worker.java | 22 +++++++ .../CountdownLatchExampleTest.java | 64 +++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/concurrent/countdownlatch/BrokenWorker.java create mode 100644 core-java/src/main/java/com/baeldung/concurrent/countdownlatch/Worker.java create mode 100644 core-java/src/test/java/com/baeldung/concurrent/countdownlatch/CountdownLatchExampleTest.java diff --git a/core-java/src/main/java/com/baeldung/concurrent/countdownlatch/BrokenWorker.java b/core-java/src/main/java/com/baeldung/concurrent/countdownlatch/BrokenWorker.java new file mode 100644 index 0000000000..90cd01b69f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/concurrent/countdownlatch/BrokenWorker.java @@ -0,0 +1,23 @@ +package com.baeldung.concurrent.countdownlatch; + +import java.util.List; +import java.util.concurrent.CountDownLatch; + +public class BrokenWorker implements Runnable { + private final List outputScraper; + private final CountDownLatch countDownLatch; + + public BrokenWorker(final List outputScraper, final CountDownLatch countDownLatch) { + this.outputScraper = outputScraper; + this.countDownLatch = countDownLatch; + } + + @Override + public void run() { + if (true) { + throw new RuntimeException("Oh dear"); + } + countDownLatch.countDown(); + outputScraper.add("Counted down"); + } +} diff --git a/core-java/src/main/java/com/baeldung/concurrent/countdownlatch/Worker.java b/core-java/src/main/java/com/baeldung/concurrent/countdownlatch/Worker.java new file mode 100644 index 0000000000..4701f26530 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/concurrent/countdownlatch/Worker.java @@ -0,0 +1,22 @@ +package com.baeldung.concurrent.countdownlatch; + +import java.util.List; +import java.util.concurrent.CountDownLatch; + +public class Worker implements Runnable { + private final List outputScraper; + private final CountDownLatch countDownLatch; + + public Worker(final List outputScraper, final CountDownLatch countDownLatch) { + this.outputScraper = outputScraper; + this.countDownLatch = countDownLatch; + } + + @Override + public void run() { + // Do some work + System.out.println("Doing some logic"); + countDownLatch.countDown(); + outputScraper.add("Counted down"); + } +} diff --git a/core-java/src/test/java/com/baeldung/concurrent/countdownlatch/CountdownLatchExampleTest.java b/core-java/src/test/java/com/baeldung/concurrent/countdownlatch/CountdownLatchExampleTest.java new file mode 100644 index 0000000000..9aa574a067 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/concurrent/countdownlatch/CountdownLatchExampleTest.java @@ -0,0 +1,64 @@ +package com.baeldung.concurrent.countdownlatch; + +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; + +public class CountdownLatchExampleTest { + @Test + public void shouldBlockUntilLatchIsReleased() throws InterruptedException { + + // Given + List outputScraper = Collections.synchronizedList(new ArrayList<>()); + CountDownLatch countDownLatch = new CountDownLatch(5); + List workers = Stream + .generate(() -> new Thread(new Worker(outputScraper, countDownLatch))) + .limit(5) + .collect(toList()); + + // When + workers.forEach(Thread::start); + countDownLatch.await(); // Block until workers finish + outputScraper.add("Latch released"); + + // Then + outputScraper.forEach(Object::toString); + assertThat(outputScraper) + .containsExactly( + "Counted down", + "Counted down", + "Counted down", + "Counted down", + "Counted down", + "Latch released" + ); + } + + @Test + public void shouldEventuallyTimeout() throws InterruptedException { + // Given + List outputScraper = Collections.synchronizedList(new ArrayList<>()); + CountDownLatch countDownLatch = new CountDownLatch(5); + List workers = Stream + .generate(() -> new Thread(new BrokenWorker(outputScraper, countDownLatch))) + .limit(5) + .collect(toList()); + + // When + workers.forEach(Thread::start); + final boolean result = countDownLatch.await(3L, TimeUnit.SECONDS); + + // Then + assertThat(result).isTrue(); + } +} \ No newline at end of file