Unit tests and DequeBasedSynchronizedStack added up
This commit is contained in:
parent
7dbca34ba4
commit
9bc5b950f6
@ -0,0 +1,36 @@
|
|||||||
|
package com.baeldung.thread_safe_lifo;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deque Based Stack implementation.
|
||||||
|
*/
|
||||||
|
public class DequeBasedSynchronizedStack<T> {
|
||||||
|
|
||||||
|
// Internal Deque which gets decorated for synchronization.
|
||||||
|
private ArrayDeque<T> dequeStore = new ArrayDeque<>();
|
||||||
|
|
||||||
|
public DequeBasedSynchronizedStack(int initialCapacity) {
|
||||||
|
this.dequeStore = new ArrayDeque<>(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DequeBasedSynchronizedStack() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized T pop() {
|
||||||
|
return this.dequeStore.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void push(T element) {
|
||||||
|
this.dequeStore.push(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized T peek() {
|
||||||
|
return this.dequeStore.peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized int size() {
|
||||||
|
return this.dequeStore.size();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
package com.baeldung.stack_tests;
|
||||||
|
|
||||||
|
import com.baeldung.thread_safe_lifo.DequeBasedSynchronizedStack;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
|
|
||||||
|
import static java.util.stream.IntStream.range;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correctness tests for Stack in multi threaded environment.
|
||||||
|
*/
|
||||||
|
public class MultithreadingCorrectnessStackTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_multithreading_correctness_with_synchronized_deque() {
|
||||||
|
|
||||||
|
DequeBasedSynchronizedStack<Integer> deque = new DequeBasedSynchronizedStack<>();
|
||||||
|
|
||||||
|
// Serial execution of push on ConcurrentLinkedQueue will always result in correct execution.
|
||||||
|
range(1, 10000).forEach(value -> deque.push(value));
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
while(deque.peek() != null) {
|
||||||
|
sum += deque.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(49995000, sum);
|
||||||
|
|
||||||
|
// Parallel execution of push on ConcurrentLinkedQueue will always result in correct execution.
|
||||||
|
range(1, 10000).parallel().forEach(value -> deque.push(value));
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
while(deque.peek() != null) {
|
||||||
|
sum += deque.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(49995000, sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_multithreading_correctness_with_concurrent_linked_queue() {
|
||||||
|
|
||||||
|
ConcurrentLinkedDeque<Integer> deque = new ConcurrentLinkedDeque<>();
|
||||||
|
|
||||||
|
// Serial execution of push on ConcurrentLinkedQueue will always result in correct execution.
|
||||||
|
range(1, 10000).forEach(value -> deque.push(value));
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
while(deque.peek() != null) {
|
||||||
|
sum += deque.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(49995000, sum);
|
||||||
|
|
||||||
|
// Parallel execution of push on ConcurrentLinkedQueue will always result in correct execution.
|
||||||
|
range(1, 10000).parallel().forEach(value -> deque.push(value));
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
while(deque.peek() != null) {
|
||||||
|
sum += deque.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(49995000, sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_multithreading_correctness_with_array_deque() {
|
||||||
|
|
||||||
|
ArrayDeque<Integer> deque = new ArrayDeque<>();
|
||||||
|
|
||||||
|
// Serial execution of push on ArrayDeque will always result in correct execution.
|
||||||
|
range(1, 10000).forEach(value -> deque.push(value));
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
while(deque.peek() != null) {
|
||||||
|
sum += deque.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(49995000, sum);
|
||||||
|
|
||||||
|
// Parallel execution of push on ArrayDeque will not result in correct execution.
|
||||||
|
range(1, 10000).parallel().forEach(value -> deque.push(value));
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
while(deque.peek() != null) {
|
||||||
|
sum += deque.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This shouldn't happen.
|
||||||
|
if(sum == 49995000) {
|
||||||
|
System.out.println("Something wrong in the environment, Please try some big value and check");
|
||||||
|
// To safe-guard build without test failures.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertNotEquals(49995000, sum);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package com.baeldung.stack_tests;
|
||||||
|
|
||||||
|
import com.baeldung.thread_safe_lifo.DequeBasedSynchronizedStack;
|
||||||
|
import com.google.common.collect.Streams;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Stack;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static java.util.stream.IntStream.range;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These tests are to understand the Stack implementation in Java Collections.
|
||||||
|
*/
|
||||||
|
public class StackTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_basic_with_stack() {
|
||||||
|
Stack<String> namesStack = new Stack<>();
|
||||||
|
|
||||||
|
namesStack.push("Bill Gates");
|
||||||
|
namesStack.push("Elon Musk");
|
||||||
|
|
||||||
|
Assert.assertEquals("Elon Musk", namesStack.peek());
|
||||||
|
Assert.assertEquals("Elon Musk", namesStack.pop());
|
||||||
|
Assert.assertEquals("Bill Gates", namesStack.pop());
|
||||||
|
|
||||||
|
Assert.assertEquals(0, namesStack.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_basic_with_synchronized_deque() {
|
||||||
|
DequeBasedSynchronizedStack<String> namesStack = new DequeBasedSynchronizedStack<>();
|
||||||
|
|
||||||
|
namesStack.push("Bill Gates");
|
||||||
|
namesStack.push("Elon Musk");
|
||||||
|
|
||||||
|
Assert.assertEquals("Elon Musk", namesStack.peek());
|
||||||
|
Assert.assertEquals("Elon Musk", namesStack.pop());
|
||||||
|
Assert.assertEquals("Bill Gates", namesStack.pop());
|
||||||
|
|
||||||
|
Assert.assertEquals(0, namesStack.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_basic_with_concurrent_linked_queue() {
|
||||||
|
ConcurrentLinkedDeque<String> namesStack = new ConcurrentLinkedDeque<>();
|
||||||
|
|
||||||
|
namesStack.push("Bill Gates");
|
||||||
|
namesStack.push("Elon Musk");
|
||||||
|
|
||||||
|
Assert.assertEquals("Elon Musk", namesStack.peek());
|
||||||
|
Assert.assertEquals("Elon Musk", namesStack.pop());
|
||||||
|
Assert.assertEquals("Bill Gates", namesStack.pop());
|
||||||
|
|
||||||
|
Assert.assertEquals(0, namesStack.size());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user