TASLock
Test-and-set Lock
import java.util.concurrent.atomic.AtomicBoolean;
public class TASLock implements SimpleLock {
AtomicBoolean locked = new AtomicBoolean(false);
public void lock () {
while (locked.getAndSet(true)) {}
}
public void unlock () {
locked.set(false);
}
}
tas-locks.zip
Question. Is TASLock
deadlock-free? Starvation-free?
Test-and-Test-and-Set Lock:
getAndSet
TTASLock
Implementationpublic class TTASLock implements SimpleLock {
AtomicBoolean locked = new AtomicBoolean(false);
public void lock () {
while (true) {
while (locked.get()) {};
if (!locked.getAndSet(true)) { return;}
}
}
public void unlock() { locked.set(false);}
}
tas-locks.zip
Locks are less efficient with more threads
Locks are not starvation free
More memory, less contention
Incorporating priority
Each thread has:
Node myNode
node “owned” by threadNode myPred
node owned by predecessor threadEach Node
has:
boolean locked
:
myNode.locked = true
signals I want/have lockmyNode.locked = false
signals I have released lockThread acquires lock when myPred.locked
is false
CLHLock
Implementationimport java.util.concurrent.atomic.AtomicReference;
public class CLHLock implements SimpleLock {
AtomicReference<QNode> tail;
ThreadLocal<QNode> myPred;
ThreadLocal<QNode> myNode;
private static class QNode {
volatile boolean locked = false;
}
}
CLHLock
Constructor public CLHLock () {
tail = new AtomicReference<QNode>(new QNode());
myNode = new ThreadLocal<QNode> () {
@Override
protected QNode initialValue() {
return new QNode();
}};
myPred = new ThreadLocal<QNode>() {
@Override
protected QNode initialValue() {
return null;
}};}
CLHLock
Lock/Unlock public void lock () {
QNode qnode = myNode.get();
qnode.locked = true;
QNode pred = tail.getAndSet(qnode);
myPred.set(pred);
while (pred.locked) {};
}
public void unlock () {
QNode qnode = myNode.get();
qnode.locked = false;
myNode.set(myPred.get());
}
clh-lock.zip
A Mystery. Why doesn’t the implementation work?
$105,097,565$ prime numbers!