Stack Assignment
Contents
Motivation
We will build three implementations of a Stack. One non-thread safe implementation, one thread-safe implementation using synchronized methods, and finally one thread-safe implementation using atomics.
Background
interface Stack
public interface Stack<E> { void push(E value); Optional<E> peek(); Optional<E> pop(); }
Example
empty
Stack<String> stack = new NotThreadSafeStack<>();
In this state, stack.peek()
will return Optional.empty()
and stack.pop()
will also return Optional.empty()
.
push A, B, C, D, E
Stack<String> stack = new NotThreadSafeStack<>(); stack.push("A"); stack.push("B"); stack.push("C"); stack.push("D"); stack.push("E");
In this state, stack.peek()
will return Optional.of("E")
.
push A, B, C, D, E, pop
Stack<String> stack = new NotThreadSafeStack<>(); stack.push("A"); stack.push("B"); stack.push("C"); stack.push("D"); stack.push("E"); Optional<String> optOfE = stack.pop();
In this state, optOfE
will hold Optional.of("E")
and stack.peek()
will return Optional.of("D")
.
Code To Implement
Node
The mighty cons cell goes back to the early days of computing. People have been building amazing systems with this data structure since the 1950s.
We will build an @Immutable class Node.
class: | DefaultNode.java | |
methods: | value nextNode |
|
package: | stack.node.exercise | |
source folder: | main/src/main/java |
constructor and instance variables
The constructor
public DefaultNode(E value, Optional<Node<E>> nextNode)
is passed a value and a nextNode. Hang on to this data in instance variables. As instances of DefaultNode are to be immutable, the instance variables should be marked as final
.
value
return the value.
nextNode
return the next node.
Stack
public interface Stack<E> { void push(E value); Optional<E> peek(); Optional<E> pop(); }
NotThreadSafeStack
class: | NotThreadSafeStack.java | |
methods: | push peek pop |
|
package: | stack.notthreadsafe.exercise | |
source folder: | student/src/main/java |
instance variables
What state do you need to keep track of to support a mutable non-thread-safe Stack?
push
peek
pop
Distasters To Investigate
ParallelPushStackDisasterClient
class: | ParallelPushStackDisasterClient.java | DEMO: |
methods: | main | |
package: | stack.notthreadsafe.disaster | |
source folder: | src/main/java |
ParallelPushAndPopStackDisasterClient
class: | ParallelPushAndPopStackDisasterClient.java | DEMO: |
methods: | main | |
package: | stack.notthreadsafe.disaster | |
source folder: | src/main/java |
Testing
class: | StackTestSuite.java | |
package: | stack.exercise | |
source folder: | testing/src/test/java |
DefaultNode
class: | _DefaultNodeTestSuite.java | |
package: | stack.node.exercise | |
source folder: | testing/src/test/java |
NotThreadSafeStack
class: | _NotThreadSafeStackTestSuite.java | |
package: | stack.notthreadsafe.exercise | |
source folder: | testing/src/test/java |
Pledge, Acknowledgments, Citations
file: | atomic-stack-pledge-acknowledgments-citations.txt |
More info about the Honor Pledge