Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-614

This commit is contained in:
Tomasz Lelek
2017-01-26 18:39:25 +01:00
205 changed files with 7435 additions and 644 deletions
+2 -1
View File
@@ -52,4 +52,5 @@
- [URL Encoding and Decoding in Java](http://www.baeldung.com/java-url-encoding-decoding)
- [Calculate the Size of a File in Java](http://www.baeldung.com/java-file-size)
- [The Basics of Java Generics](http://www.baeldung.com/java-generics)
- [The Traveling Salesman Problem in Java](http://www.baeldung.com/java-simulated-annealing-for-traveling-salesman)
- [The Traveling Salesman Problem in Java](http://www.baeldung.com/java-simulated-annealing-for-traveling-salesman)
- [How to Create an Executable JAR with Maven](http://www.baeldung.com/executable-jar-with-maven)
-6
View File
@@ -64,11 +64,6 @@
<version>${grep4j.version}</version>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>${disruptor.version}</version>
</dependency>
<!-- web -->
<!-- marshalling -->
@@ -369,7 +364,6 @@
<unix4j.version>0.4</unix4j.version>
<grep4j.version>1.8.7</grep4j.version>
<lombok.version>1.16.12</lombok.version>
<disruptor.version>3.3.6</disruptor.version>
<!-- testing -->
<org.hamcrest.version>1.3</org.hamcrest.version>
@@ -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<String> outputScraper;
private final CountDownLatch countDownLatch;
public BrokenWorker(final List<String> 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");
}
}
@@ -0,0 +1,37 @@
package com.baeldung.concurrent.countdownlatch;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class WaitingWorker implements Runnable {
private final List<String> outputScraper;
private final CountDownLatch readyThreadCounter;
private final CountDownLatch callingThreadBlocker;
private final CountDownLatch completedThreadCounter;
public WaitingWorker(final List<String> outputScraper,
final CountDownLatch readyThreadCounter,
final CountDownLatch callingThreadBlocker,
CountDownLatch completedThreadCounter) {
this.outputScraper = outputScraper;
this.readyThreadCounter = readyThreadCounter;
this.callingThreadBlocker = callingThreadBlocker;
this.completedThreadCounter = completedThreadCounter;
}
@Override
public void run() {
// Mark this thread as read / started
readyThreadCounter.countDown();
try {
callingThreadBlocker.await();
outputScraper.add("Counted down");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
completedThreadCounter.countDown();
}
}
}
@@ -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<String> outputScraper;
private final CountDownLatch countDownLatch;
public Worker(final List<String> 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");
}
}
@@ -1,34 +0,0 @@
package com.baeldung.disruptor;
import com.lmax.disruptor.RingBuffer;
public class DelayedMultiEventProducer implements EventProducer {
@Override
public void startProducing(final RingBuffer<ValueEvent> ringBuffer, final int count) {
final Runnable simpleProducer = () -> produce(ringBuffer, count, false);
final Runnable delayedProducer = () -> produce(ringBuffer, count, true);
new Thread(simpleProducer).start();
new Thread(delayedProducer).start();
}
private void produce(final RingBuffer<ValueEvent> ringBuffer, final int count, final boolean addDelay) {
for (int i = 0; i < count; i++) {
final long seq = ringBuffer.next();
final ValueEvent valueEvent = ringBuffer.get(seq);
valueEvent.setValue(i);
ringBuffer.publish(seq);
if (addDelay) {
addDelay();
}
}
}
private void addDelay() {
try {
Thread.sleep(1000);
} catch (InterruptedException interruptedException) {
// No-Op lets swallow it
}
}
}
@@ -1,13 +0,0 @@
package com.baeldung.disruptor;
import com.lmax.disruptor.EventHandler;
/**
* Consumer that consumes event from ring buffer.
*/
public interface EventConsumer {
/**
* One or more event handler to handle event from ring buffer.
*/
public EventHandler<ValueEvent>[] getEventHandler();
}
@@ -1,15 +0,0 @@
package com.baeldung.disruptor;
import com.lmax.disruptor.RingBuffer;
/**
* Producer that produces event for ring buffer.
*/
public interface EventProducer {
/**
* Start the producer that would start producing the values.
* @param ringBuffer
* @param count
*/
public void startProducing(final RingBuffer<ValueEvent> ringBuffer, final int count);
}
@@ -1,23 +0,0 @@
package com.baeldung.disruptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lmax.disruptor.EventHandler;
public class MultiEventPrintConsumer implements EventConsumer {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
@SuppressWarnings("unchecked")
public EventHandler<ValueEvent>[] getEventHandler() {
final EventHandler<ValueEvent> eventHandler = (event, sequence, endOfBatch) -> print(event.getValue(), sequence);
final EventHandler<ValueEvent> otherEventHandler = (event, sequence, endOfBatch) -> print(event.getValue(), sequence);
return new EventHandler[] { eventHandler, otherEventHandler };
}
private void print(final int id, final long sequenceId) {
logger.info("Id is " + id + " sequence id that was used is " + sequenceId);
}
}
@@ -1,22 +0,0 @@
package com.baeldung.disruptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lmax.disruptor.EventHandler;
public class SingleEventPrintConsumer implements EventConsumer {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
@SuppressWarnings("unchecked")
public EventHandler<ValueEvent>[] getEventHandler() {
final EventHandler<ValueEvent> eventHandler = (event, sequence, endOfBatch) -> print(event.getValue(), sequence);
return new EventHandler[] { eventHandler };
}
private void print(final int id, final long sequenceId) {
logger.info("Id is " + id + " sequence id that was used is " + sequenceId);
}
}
@@ -1,22 +0,0 @@
package com.baeldung.disruptor;
import com.lmax.disruptor.RingBuffer;
public class SingleEventProducer implements EventProducer {
@Override
public void startProducing(RingBuffer<ValueEvent> ringBuffer, int count) {
final Runnable producer = () -> produce(ringBuffer, count);
new Thread(producer).start();
}
private void produce(final RingBuffer<ValueEvent> ringBuffer, final int count) {
for (int i = 0; i < count; i++) {
final long seq = ringBuffer.next();
final ValueEvent valueEvent = ringBuffer.get(seq);
valueEvent.setValue(i);
ringBuffer.publish(seq);
}
}
}
@@ -1,25 +0,0 @@
package com.baeldung.disruptor;
import org.apache.commons.lang3.builder.ToStringBuilder;
import com.lmax.disruptor.EventFactory;
public final class ValueEvent {
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public final static EventFactory<ValueEvent> EVENT_FACTORY = () -> new ValueEvent();
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
@@ -0,0 +1,96 @@
package com.baeldung.concurrent.countdownlatch;
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.stream.Stream;
import static java.util.stream.Collectors.toList;
import static org.assertj.core.api.Assertions.assertThat;
public class CountdownLatchExampleTest {
@Test
public void whenParallelProcessing_thenMainThreadWillBlockUntilCompletion() throws InterruptedException {
// Given
List<String> outputScraper = Collections.synchronizedList(new ArrayList<>());
CountDownLatch countDownLatch = new CountDownLatch(5);
List<Thread> 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 whenFailingToParallelProcess_thenMainThreadShouldTimeout() throws InterruptedException {
// Given
List<String> outputScraper = Collections.synchronizedList(new ArrayList<>());
CountDownLatch countDownLatch = new CountDownLatch(5);
List<Thread> 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).isFalse();
}
@Test
public void whenDoingLotsOfThreadsInParallel_thenStartThemAtTheSameTime() throws InterruptedException {
// Given
List<String> outputScraper = Collections.synchronizedList(new ArrayList<>());
CountDownLatch readyThreadCounter = new CountDownLatch(5);
CountDownLatch callingThreadBlocker = new CountDownLatch(1);
CountDownLatch completedThreadCounter = new CountDownLatch(5);
List<Thread> workers = Stream
.generate(() -> new Thread(new WaitingWorker(outputScraper, readyThreadCounter, callingThreadBlocker, completedThreadCounter)))
.limit(5)
.collect(toList());
// When
workers.forEach(Thread::start);
readyThreadCounter.await(); // Block until workers start
outputScraper.add("Workers ready");
callingThreadBlocker.countDown(); // Start workers
completedThreadCounter.await(); // Block until workers finish
outputScraper.add("Workers complete");
// Then
outputScraper.forEach(Object::toString);
assertThat(outputScraper)
.containsExactly(
"Workers ready",
"Counted down",
"Counted down",
"Counted down",
"Counted down",
"Counted down",
"Workers complete"
);
}
}
@@ -1,83 +0,0 @@
package com.baeldung.disruptor;
import java.util.concurrent.ThreadFactory;
import org.junit.Before;
import org.junit.Test;
import com.lmax.disruptor.BusySpinWaitStrategy;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.WaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import com.lmax.disruptor.util.DaemonThreadFactory;
public class DisruptorTest {
private Disruptor<ValueEvent> disruptor;
private WaitStrategy waitStrategy;
@Before
public void setUp() throws Exception {
waitStrategy = new BusySpinWaitStrategy();
}
private void createDisruptor(final ProducerType producerType, final EventConsumer eventConsumer) {
final ThreadFactory threadFactory = DaemonThreadFactory.INSTANCE;
disruptor = new Disruptor<ValueEvent>(ValueEvent.EVENT_FACTORY, 16, threadFactory, producerType, waitStrategy);
disruptor.handleEventsWith(eventConsumer.getEventHandler());
}
private void startProducing(final RingBuffer<ValueEvent> ringBuffer, final int count, final EventProducer eventProducer) {
eventProducer.startProducing(ringBuffer, count);
}
@Test
public void whenMultipleProducerSingleConsumer_thenOutputInFifoOrder() {
final EventConsumer eventConsumer = new SingleEventPrintConsumer();
final EventProducer eventProducer = new DelayedMultiEventProducer();
createDisruptor(ProducerType.MULTI, eventConsumer);
final RingBuffer<ValueEvent> ringBuffer = disruptor.start();
startProducing(ringBuffer, 32, eventProducer);
disruptor.halt();
disruptor.shutdown();
}
@Test
public void whenSingleProducerSingleConsumer_thenOutputInFifoOrder() {
final EventConsumer eventConsumer = new SingleEventConsumer();
final EventProducer eventProducer = new SingleEventProducer();
createDisruptor(ProducerType.SINGLE, eventConsumer);
final RingBuffer<ValueEvent> ringBuffer = disruptor.start();
startProducing(ringBuffer, 32, eventProducer);
disruptor.halt();
disruptor.shutdown();
}
@Test
public void whenSingleProducerMultipleConsumer_thenOutputInFifoOrder() {
final EventConsumer eventConsumer = new MultiEventConsumer();
final EventProducer eventProducer = new SingleEventProducer();
createDisruptor(ProducerType.SINGLE, eventConsumer);
final RingBuffer<ValueEvent> ringBuffer = disruptor.start();
startProducing(ringBuffer, 32, eventProducer);
disruptor.halt();
disruptor.shutdown();
}
@Test
public void whenMultipleProducerMultipleConsumer_thenOutputInFifoOrder() {
final EventConsumer eventConsumer = new MultiEventPrintConsumer();
final EventProducer eventProducer = new DelayedMultiEventProducer();
createDisruptor(ProducerType.MULTI, eventConsumer);
final RingBuffer<ValueEvent> ringBuffer = disruptor.start();
startProducing(ringBuffer, 32, eventProducer);
disruptor.halt();
disruptor.shutdown();
}
}
@@ -1,27 +0,0 @@
package com.baeldung.disruptor;
import static org.junit.Assert.assertEquals;
import com.lmax.disruptor.EventHandler;
public class MultiEventConsumer implements EventConsumer {
private int expectedValue = -1;
private int otherExpectedValue = -1;
@Override
@SuppressWarnings("unchecked")
public EventHandler<ValueEvent>[] getEventHandler() {
final EventHandler<ValueEvent> eventHandler = (event, sequence, endOfBatch) -> assertExpectedValue(event.getValue());
final EventHandler<ValueEvent> otherEventHandler = (event, sequence, endOfBatch) -> assertOtherExpectedValue(event.getValue());
return new EventHandler[] { eventHandler, otherEventHandler };
}
private void assertExpectedValue(final int id) {
assertEquals(++expectedValue, id);
}
private void assertOtherExpectedValue(final int id) {
assertEquals(++otherExpectedValue, id);
}
}
@@ -1,21 +0,0 @@
package com.baeldung.disruptor;
import static org.junit.Assert.assertEquals;
import com.lmax.disruptor.EventHandler;
public class SingleEventConsumer implements EventConsumer {
private int expectedValue = -1;
@Override
@SuppressWarnings("unchecked")
public EventHandler<ValueEvent>[] getEventHandler() {
final EventHandler<ValueEvent> eventHandler = (event, sequence, endOfBatch) -> assertExpectedValue(event.getValue());
return new EventHandler[] { eventHandler };
}
private void assertExpectedValue(final int id) {
assertEquals(++expectedValue, id);
}
}
@@ -1,10 +1,8 @@
package com.baeldung.guava;
import static org.junit.Assert.*;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import com.google.common.collect.BiMap;
import com.google.common.collect.EnumHashBiMap;
@@ -13,32 +11,32 @@ import com.google.common.collect.ImmutableBiMap;
public class GuavaBiMapTest {
@Test
public void whenQueryByValue_shouldReturnKey() {
public void whenQueryByValue_returnsKey() {
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
capitalCountryBiMap.put("New Delhi", "India");
capitalCountryBiMap.put("Washingon, D.C.", "USA");
capitalCountryBiMap.put("Moscow", "Russia");
final String countryHeadName = capitalCountryBiMap.inverse().get("India");
final String countryCapitalName = capitalCountryBiMap.inverse().get("India");
assertEquals("New Delhi", countryHeadName);
assertEquals("New Delhi", countryCapitalName);
}
@Test
public void whenCreateBiMapFromExistingMap_shouldReturnKey() {
final Map<String, String> personCountryHeadMap = new HashMap<>();
personCountryHeadMap.put("New Delhi", "India");
personCountryHeadMap.put("Washingon, D.C.", "USA");
personCountryHeadMap.put("Moscow", "Russia");
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create(personCountryHeadMap);
public void whenCreateBiMapFromExistingMap_returnsKey() {
final Map<String, String> capitalCountryMap = new HashMap<>();
capitalCountryMap.put("New Delhi", "India");
capitalCountryMap.put("Washingon, D.C.", "USA");
capitalCountryMap.put("Moscow", "Russia");
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create(capitalCountryMap);
final String countryHeadName = capitalCountryBiMap.inverse().get("India");
final String countryCapitalName = capitalCountryBiMap.inverse().get("India");
assertEquals("New Delhi", countryHeadName);
assertEquals("New Delhi", countryCapitalName);
}
@Test
public void whenQueryByKey_shouldReturnValue() {
public void whenQueryByKey_returnsValue() {
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
capitalCountryBiMap.put("New Delhi", "India");
@@ -49,7 +47,7 @@ public class GuavaBiMapTest {
}
@Test(expected = IllegalArgumentException.class)
public void whenSameValueIsBeingPresent_shouldThrowException() {
public void whenSameValueIsPresent_throwsException() {
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
capitalCountryBiMap.put("New Delhi", "India");
@@ -59,7 +57,7 @@ public class GuavaBiMapTest {
}
@Test
public void givenSameValueIsBeingPresent_whenForcePutIsUsed_shouldCompleteSuccessfully() {
public void givenSameValueIsPresent_whenForcePut_completesSuccessfully() {
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
capitalCountryBiMap.put("New Delhi", "India");
@@ -72,7 +70,7 @@ public class GuavaBiMapTest {
}
@Test
public void whenSameKeyIsBeingPresent_shouldReplaceAlreadyPresent() {
public void whenSameKeyIsPresent_replacesAlreadyPresent() {
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
capitalCountryBiMap.put("New Delhi", "India");
@@ -84,21 +82,21 @@ public class GuavaBiMapTest {
}
@Test
public void whenUsingImmutableBiMap_shouldAllowPutSuccessfully() {
public void whenUsingImmutableBiMap_allowsPutSuccessfully() {
final BiMap<String, String> capitalCountryBiMap = new ImmutableBiMap.Builder<String, String>().put("New Delhi", "India").put("Washingon, D.C.", "USA").put("Moscow", "Russia").build();
assertEquals("USA", capitalCountryBiMap.get("Washingon, D.C."));
}
@Test(expected = UnsupportedOperationException.class)
public void whenUsingImmutableBiMap_shouldNotAllowRemove() {
public void whenUsingImmutableBiMap_doesntAllowRemove() {
final BiMap<String, String> capitalCountryBiMap = new ImmutableBiMap.Builder<String, String>().put("New Delhi", "India").put("Washingon, D.C.", "USA").put("Moscow", "Russia").build();
capitalCountryBiMap.remove("New Delhi");
}
@Test(expected = UnsupportedOperationException.class)
public void whenUsingImmutableBiMap_shouldNotAllowPut() {
public void whenUsingImmutableBiMap_doesntAllowPut() {
final BiMap<String, String> capitalCountryBiMap = new ImmutableBiMap.Builder<String, String>().put("New Delhi", "India").put("Washingon, D.C.", "USA").put("Moscow", "Russia").build();
capitalCountryBiMap.put("New York", "USA");
@@ -109,7 +107,7 @@ public class GuavaBiMapTest {
}
@Test
public void whenUsingEnumAsKeyInMap_shouldReplaceAlreadyPresent() {
public void whenUsingEnumAsKeyInMap_replacesAlreadyPresent() {
final BiMap<Operation, String> operationStringBiMap = EnumHashBiMap.create(Operation.class);
operationStringBiMap.put(Operation.ADD, "Add");
@@ -119,4 +117,4 @@ public class GuavaBiMapTest {
assertEquals("Divide", operationStringBiMap.get(Operation.DIVIDE));
}
}
}
@@ -311,13 +311,7 @@ public class MapTest {
@Test
public void givenTreeMap_whenOrdersEntriesByComparator_thenCorrect() {
TreeMap<Integer, String> map = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
TreeMap<Integer, String> map = new TreeMap<>(Comparator.reverseOrder());
map.put(3, "val");
map.put(2, "val");
map.put(1, "val");
@@ -17,7 +17,7 @@ public class Java8FindAnyFindFirstTest {
@Test
public void createStream_whenFindAnyResultIsPresent_thenCorrect() {
List<String> list = Arrays.asList("A","B","C","D");
List<String> list = Arrays.asList("A", "B", "C", "D");
Optional<String> result = list.stream().findAny();
@@ -25,14 +25,27 @@ public class Java8FindAnyFindFirstTest {
assertThat(result.get(), anyOf(is("A"), is("B"), is("C"), is("D")));
}
@Test
public void createParallelStream_whenFindAnyResultIsPresent_thenCorrect() throws Exception {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> result = list
.stream()
.parallel()
.filter(num -> num < 4)
.findAny();
assertTrue(result.isPresent());
assertThat(result.get(), anyOf(is(1), is(2), is(3)));
}
@Test
public void createStream_whenFindFirstResultIsPresent_thenCorrect() {
List<String> list = Arrays.asList("A","B","C","D");
List<String> list = Arrays.asList("A", "B", "C", "D");
Optional<String> result = list.stream().findFirst();
assertTrue(result.isPresent());
assertThat(result.get(),is("A"));
assertThat(result.get(), is("A"));
}
}