push(x), pop()
An execution of a shared object is linearizable if:
An implementation of an object is linearizable if every execution is linearizable.

TwoCounter
public class TwoCounter {
int[] counts = new int[2];
public void increment (int amt) {
int i = ThreadID.get(); // thread IDs are 0 and 1
int count = counts[i];
counts[i] = count + amt;
}
public int read () {
int count = counts[0];
count = count + counts[1];
return count;
}}
ThreeCounter Examplepublic class ThreeCounter {
int[] counts = new int[3];
public void increment (int amt) {
int i = ThreadID.get(); // thread IDs are 0, 1, and 2
int count = counts[i];
counts[i] = count + amt;
}
}
read Method public int read () {
int count = counts[0];
count = count + counts[1];
count = count + counts[2];
return count;
}
ThreeCounter Linearizable? public int read () {
int count = counts[0];
count = count + counts[1];
count = count + counts[2];
return count;
}
Questions.
ThreeCounter sequentially consistent?Question. How to implement a (non-concurrent) queue with a linked list?
Node head sentinal
deq returns head.next value (if any), updates head
Node tail
enq updates tail.next, updates tail
enqLock locks enq operationdeqLock locks deq operationNodes are not locked
deqLock


head



enqLock

tail.next

tail


Why do we need the sentinel node?
UnboundedQueue in Codepublic class UnboundedQueue<T> implements SimpleQueue<T> {
final ReentrantLock enqLock;
final ReentrantLock deqLock;
volatile Node head;
volatile Node tail;
public UnboundedQueue() {
head = new Node(null); tail = head;
enqLock = new ReentrantLock();
deqLock = new ReentrantLock(); }
...
}
Node Class class Node {
final T value;
volatile Node next;
public Node (T value) {
this.value = value;
}
}
enq Method public void enq (T value) {
enqLock.lock();
try {
Node nd = new Node(value);
tail.next = nd;
tail = nd;
} finally {
enqLock.unlock();
}
}
deq Method public T deq() throws EmptyException {
T value;
deqLock.lock();
try {
if (head.next == null){throw new EmptyException();}
value = head.next.value;
head = head.next;
return value;
} finally {
deqLock.unlock();
}
}
UnboundedQueue Linearizable? public void enq (T value) {
Node nd = new Node(value);
tail.next = nd;
tail = nd;
}
public T deq() throws EmptyException {
if (head.next == null){throw new EmptyException();}
value = head.next.value;
head = head.next;
return value;
}
Concurrent queues without locks?!?!