stack
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
stack [2007/10/28 16:43] – external edit 127.0.0.1 | stack [2009/05/06 19:58] (current) – franck | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | Below we implement the following Stack interface in several different ways. | ||
- | |||
<code java> | <code java> | ||
/** | /** | ||
* A Stack. | * A Stack. | ||
*/ | */ | ||
- | public interface Stack | + | public interface Stack<T> |
{ | { | ||
/** | /** | ||
Line 11: | Line 9: | ||
* | * | ||
* @return the top element of this stack. | * @return the top element of this stack. | ||
- | * @throw | + | * @throw |
*/ | */ | ||
- | public | + | public |
+ | |||
/** | /** | ||
* Pushes the given element onto this stack. | * Pushes the given element onto this stack. | ||
Line 20: | Line 18: | ||
* @param the element to be pushed onto this stack. | * @param the element to be pushed onto this stack. | ||
*/ | */ | ||
- | public void push(Integer | + | public void push(T element); |
} | } | ||
</ | </ | ||
- | In each implementation of the above interface we will exploit the class Node. | + | In each implementation of the above interface we will exploit the class Node. |
<code java> | <code java> | ||
/** | /** | ||
- | * A node of a linked list. Each node contains an integer. | + | * A node of a linked list. |
*/ | */ | ||
- | public class Node | + | public class Node<T> |
{ | { | ||
- | private | + | private |
- | private Node next; | + | private Node< |
+ | |||
/** | /** | ||
- | | + | |
* | * | ||
* @param element the element stored in the node. | * @param element the element stored in the node. | ||
Line 42: | Line 40: | ||
* @param next the next node in the list. | * @param next the next node in the list. | ||
*/ | */ | ||
- | public Node(Integer | + | public Node(T element, Node< |
{ | { | ||
this.element = element; | this.element = element; | ||
this.next = next; | this.next = next; | ||
} | } | ||
+ | | ||
/** | /** | ||
* Returns the element of this node. | * Returns the element of this node. | ||
Line 53: | Line 51: | ||
* @return the element of this node. | * @return the element of this node. | ||
*/ | */ | ||
- | public | + | public |
{ | { | ||
return this.element; | return this.element; | ||
} | } | ||
+ | | ||
/** | /** | ||
* Returns the next node. | * Returns the next node. | ||
Line 63: | Line 61: | ||
* @return the next node. | * @return the next node. | ||
*/ | */ | ||
- | public Node getNext() | + | public Node< |
{ | { | ||
return this.next; | return this.next; | ||
} | } | ||
+ | | ||
/** | /** | ||
* Sets the next node to the given node. | * Sets the next node to the given node. | ||
Line 73: | Line 71: | ||
* @param node the new next node. | * @param node the new next node. | ||
*/ | */ | ||
- | public void setNext(Node next) | + | public void setNext(Node< |
{ | { | ||
this.next = next; | this.next = next; | ||
Line 80: | Line 78: | ||
</ | </ | ||
- | In the first implementation, | + | In the first implementation, |
<code java> | <code java> | ||
- | public class Stack1 | + | public class First< |
{ | { | ||
- | private Node top; | + | private Node< |
- | + | ||
- | /** | + | public |
- | * Creates an empty stack. | + | |
- | */ | + | |
- | public | + | |
{ | { | ||
this.top = null; | this.top = null; | ||
} | } | ||
- | + | | |
- | public synchronized | + | public synchronized |
{ | { | ||
if (this.top == null) | if (this.top == null) | ||
{ | { | ||
- | throw new EmptyException(); | + | throw new Exception(); |
} | } | ||
else | else | ||
{ | { | ||
- | | + | |
this.top = this.top.getNext(); | this.top = this.top.getNext(); | ||
return element; | return element; | ||
} | } | ||
} | } | ||
- | + | | |
- | public synchronized void push(Integer | + | public synchronized void push(T element) |
{ | { | ||
- | this.top = new Node(element, | + | this.top = new Node<T>(element, this.top); |
} | } | ||
} | } | ||
</ | </ | ||
- | In the second implementation, | + | In the second implementation, |
<code java> | <code java> | ||
- | public class Stack2 | + | public class Second< |
{ | { | ||
- | private Node top; | + | private Node< |
- | + | ||
- | | + | public |
- | * Creates an empty stack. | + | |
- | */ | + | |
- | public | + | |
{ | { | ||
- | this.top = new Node(null, null); | + | this.top = null; |
} | } | ||
- | + | | |
- | public | + | public |
{ | { | ||
+ | Node< | ||
synchronized (this.top) | synchronized (this.top) | ||
{ | { | ||
- | if (this.top.getNext() | + | if (this.top == null) |
{ | { | ||
- | throw new EmptyException(); | + | throw new Exception(); |
} | } | ||
else | else | ||
{ | { | ||
- | | + | |
this.top = this.top.getNext(); | this.top = this.top.getNext(); | ||
- | return element; | ||
} | } | ||
} | } | ||
+ | return node.getElement(); | ||
} | } | ||
- | + | | |
- | public void push(Integer | + | public void push(T element) |
{ | { | ||
- | Node node = new Node(element, | + | Node< |
synchronized (this.top) | synchronized (this.top) | ||
{ | { | ||
Line 160: | Line 153: | ||
</ | </ | ||
- | The third implementation does not use any locking. | + | The third implementation does not use any locking. We exploit the class AtomicReference. |
<code java> | <code java> | ||
import java.util.concurrent.atomic.*; | import java.util.concurrent.atomic.*; | ||
- | + | | |
- | public class Stack3 | + | public class Third< |
{ | { | ||
- | private volatile AtomicReference< | + | private volatile AtomicReference< |
- | + | ||
- | | + | public |
- | * Creates an empty stack. | + | |
- | */ | + | |
- | public | + | |
{ | { | ||
- | this.top = new AtomicReference< | + | this.top = new AtomicReference< |
} | } | ||
- | + | | |
- | public | + | public |
{ | { | ||
- | Node node; | + | Node< |
do | do | ||
{ | { | ||
Line 185: | Line 175: | ||
if (node == null) | if (node == null) | ||
{ | { | ||
- | throw new EmptyException(); | + | throw new Exception(); |
} | } | ||
} | } | ||
Line 191: | Line 181: | ||
return node.getElement(); | return node.getElement(); | ||
} | } | ||
- | + | | |
- | public void push(Integer | + | public void push(T element) |
{ | { | ||
- | Node node = new Node(element, | + | Node< |
do | do | ||
{ | { | ||
Line 204: | Line 194: | ||
</ | </ | ||
- | Also the fourth implementation does not use any locking. | + | Also the fourth implementation does not use any locking. This time we exploit the class AtomicReferenceFieldUpdater. |
<code java> | <code java> | ||
import java.util.concurrent.atomic.*; | import java.util.concurrent.atomic.*; | ||
- | + | | |
- | public class Stack4 | + | public class Fourth< |
{ | { | ||
- | private volatile Node top; | + | private volatile Node< |
- | + | ||
- | private static final AtomicReferenceFieldUpdater< | + | private static final AtomicReferenceFieldUpdater< |
- | 4.class, Node.class, " | + | |
- | + | ||
- | | + | public |
- | * Creates an empty stack. | + | |
- | */ | + | |
- | public | + | |
{ | { | ||
this.top = null; | this.top = null; | ||
} | } | ||
- | + | | |
- | public | + | public |
{ | { | ||
- | Node node; | + | Node< |
do | do | ||
{ | { | ||
Line 232: | Line 219: | ||
if (node == null) | if (node == null) | ||
{ | { | ||
- | throw new EmptyException(); | + | throw new Exception(); |
} | } | ||
- | } while (!Stack4.topUpdater.compareAndSet(this, | + | } |
+ | | ||
return node.getElement(); | return node.getElement(); | ||
} | } | ||
- | + | | |
- | public void push(Integer | + | public void push(T element) |
{ | { | ||
- | Node node = new Node(element, | + | Node< |
do | do | ||
{ | { | ||
node.setNext(this.top); | node.setNext(this.top); | ||
} | } | ||
- | while (!Stack4.topUpdater.compareAndSet(this, | + | while (Fourth.topUpdater.compareAndSet(this, |
} | } | ||
} | } | ||
</ | </ | ||
stack.1193589836.txt.gz · Last modified: 2009/04/26 19:37 (external edit)