首页 > 数据库 > 数据库开发技术 > 并发编程的艺术05-队列自旋锁


Queue Spin-Lock


Anderson Queue Lock
public class ALock implements Lock {ThreadLocal<Integer> mySlotIndex = new ThreadLocal() {protected Integer initiaValue() {return 0;}};AtomicInteger tail;boolean[] flag;int size;public ALock(int capacity) {size = capacity;tail = new AtomicInteger(0);flag = new boolean[capacity];flag[0] = true;}public void lock() {int slot = tail.getAndIncrement() % size;mySlotIndex.set(slot);while (! flag[slot]) {}// Prepare slot for re-useflag[slot] = false;}public void unlock() {Integer slot = mySlotIndex.get();flag[(slot + 1) % size] = true;}}


CLH Lock
class QNode {public locked = false;}public class CLHLock implements Lock {AtomicReference<QNode> tail = new AtomicReference<QNode>(new QNode());ThreadLocal<QNode> myNode, myPred;public CLHLock() {myNode = new ThreadLocal<QNode>() {protected QNode initialValue() {return new QNode();}};myPred = new ThreadLocal<QNode>() {protected QNode initialValue() {return null;}};}public void lock() {QNode qnode = myNode.get();qnode.locked = true;QNode pred = tail.getAndSet(qnode);myPred.set(pred);// Spin until predecessor releases lockwhile (pred.locked) {}}public void unlock() {QNode qnode = myNode.get();qnode.locked = false;myNode.set(myPred.get());}}

MCS Lock
class QNode {public locked = false;public QNode next;}public class MCSLock implements Lock {AtomicReference<QNode> tail = new AtomicReference<QNode>(null);ThreadLocal<QNode> myNode;public MCSLock () {myNode = new ThreadLocal<QNode>() {protected QNode initialValue() {return new QNode();}};}public void lock() {QNode qnode = myNode.get();QNode pred = tail.getAndSet(qnode);if (pred != null) {qnode.locked = true;pred.next = qnode;while (qnode.locked) {}}}public void unlock() {QNode qnode = myNode.get();if (qnode.next == null) {if (tail.compareAndSet(qnode , null))) {return;}while (qnode.next == null) {}}qnode.next.locked = false;qnode.next = null;}}

时限队列锁
class QNode {public QNode pred;}public class TOLock implements Lock {static QNode AVAILABLE = new QNode();AtomicReference<QNode> tail = new AtomicReference<QNode>(null);ThreadLocal<QNode> myNode;public TOLock() {myNode = new ThreadLocal<QNode>() {protected QNode initialValue() {return new QNode();}};}public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {long startTime = System.nanoTime();long patience = TimeUnit.NANOSECONDS.convert(time, unit);QNode qnode = new QNode();myNode.set(qnode); // remember for unlockqnode.pred = null;QNode pred = tail.getAndSet(qnode);if (pred == null || pred.pred == AVAILABLE) {return true; // lock was free; just return}while (System.nanoTime() - startTime < patience) {QNode predPred = pred.pred;if (predPred == AVAILABLE) {return true;} else if (predPred != null) { // skip predecessorspred = predPred;}}// timed out; reclaim or abandon own nodeif (!tail.compareAndSet(qnode, pred))qnode.pred = pred;return false;}public void unlock() {QNode qnode = myNode.get();if (! tail.compareAndSet(qnode, null))qnode.pred = AVAILABLE;}public void lock() {try {tryLock(Long.MAX_VALUE, TimeUnit.NANOSECONDS);} catch (InterruptedException ex) {ex.printStackTrace();}}}

到这里队列自旋锁算法就讲完了,希望对你有帮助,如果觉得有收获还请点击"再看"支持作者。本人才疏学浅,如果文中有不当之处还请留言指正。

往期精彩回顾

原文作者:DevXTalk;如有侵权,请联系管理员删除。