1、非公平锁,可能导致饥饿
2、依赖一个互斥标记,线程较多时竞技激烈,且多个CPU高速缓存同步频繁
3、实现非公平锁需要额外的字段
加锁
解锁
interface Lock {
void lock();
void unlock() throws Exception;
}
class CLHLock implements Lock {
/**
* tailNode 尾节点原子操作保证线程安全
*/
private final AtomicReference<Node> tailNode = new AtomicReference<>();
private final ThreadLocal<Node> currentNodeLocal = new ThreadLocal<>();
private static class Node {
/**
* 前驱节点
*/
private Node preNode;
/**
* 当前节点状态
* volatile 保证对后置线程的可见性
*/
private volatile Boolean lockState;
public Node(Boolean lockState) {
this.lockState = lockState;
}
}
@Override
public void lock() {
Node currentNode = currentNodeLocal.get();
if (currentNode == null) {
currentNodeLocal.set(new Node(true));
currentNode = currentNodeLocal.get();
}
// 拿到当前节点的前置节点 形成逻辑连接 无实际连接
Node preNode = tailNode.getAndSet(currentNode);
// 检查前置节点 lock state
while (currentNode.preNode != null && preNode.lockState) {
System.out.println(Thread.currentThread().getName() + " 自旋等待获取锁");
}
System.out.println(Thread.currentThread().getName() + " 获取锁成功");
}
@Override
public void unlock() throws Exception {
Node currentNode = currentNodeLocal.get();
if (!currentNode.lockState || (currentNode.preNode != null && currentNode.preNode.lockState)) {
throw new Exception("current thread is not locked");
}
currentNode.lockState = false;
// 清除线程 ThreadLocal 本次锁信息 避免拿到已经释放的锁信息
currentNodeLocal.remove();
System.out.println(Thread.currentThread().getName() + " 释放锁");
}
}
加锁
解锁
interface Lock {
void lock();
void unlock() throws Exception;
}
class MSCLock implements Lock {
/**
* tailNode 尾节点原子操作保证线程安全
*/
final AtomicReference<Node> tailNode = new AtomicReference<>();
private final ThreadLocal<Node> currentNodeLocal = new ThreadLocal<>();
private static class Node {
/**
* 后驱节点
* volatile 保证 nextNode 引用的可见性
*/
private volatile Node nextNode;
/**
* 当前节点状态
* volatile 保证对后置线程的可见性
*/
private volatile Boolean lockState;
public Node(Boolean lockState) {
this.lockState = lockState;
}
}
@Override
public void lock() {
Node currentNode = new Node(true);
currentNodeLocal.set(currentNode);
Node preNode = tailNode.getAndSet(currentNode);
// 首节点直接获取锁
if (preNode == null) {
currentNode.lockState = true;
} else {
preNode.nextNode = currentNode;
// 自旋检测当前节点状态
while (!currentNode.lockState) {
System.out.println(Thread.currentThread().getName() + " 自旋等待获取锁");
}
}
System.out.println(Thread.currentThread().getName() + " 获取锁成功");
}
@Override
public void unlock() {
Node currentNode = currentNodeLocal.get();
Node nextNode = currentNode.nextNode;
// 若无等待线程 尝试将tailNode置为 null
if (nextNode == null) {
if (tailNode.compareAndSet(currentNode, null)) {
System.out.println(Thread.currentThread().getName() + " 锁释放成功");
return;
} else {
nextNode = currentNode.nextNode;
}
}
// 清除线程 ThreadLocal 本次锁信息 避免拿到已经释放的锁信息
currentNodeLocal.remove();
// 唤醒下一个等待线程
nextNode.lockState = true;
}
}
阅读量:2017
点赞量:0
收藏量:0