1.lock流程图 2.unlock参考小刘讲源码
unlock的流程相对简单,就是将state置为0,将exclusiveOwnerThread置为NULL(不考虑重入不考虑失败),然后将队列中下一个节点唤醒。
3.代码定义一个Lock接口
public interface Lock {
void lock();
void unlock();
}
实现Lock接口实现自定义锁
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.util.concurrent.locks.LockSupport;
public class MiniReentrantLock implements Lock {
private volatile int state;
private Thread exclusiveOwnerThread;
private Node head; //head节点对应的线程 就是当前获取锁的线程
private Node tail; //尾结点
static class Node {
Node prev; //前置节点
Node next; //后置节点
Thread thread; //封装的线程本身。
public Node() {
}
public Node(Thread thread) {
this.thread = thread;
}
public Node(Thread thread, Node prev, Node next) {
this.thread = thread;
this.prev = prev;
this.next = next;
}
}
@Override
public void lock() {
acquire(1);
}
private void acquire(int arg) {
//尝试获取锁失败
if (!tryAcquire(arg)) {
//入队
Node node = addWaiter();
//在队列中尝试获取锁
acquireQueued(node, arg);
}
}
private void acquireQueued(Node node, int arg) {
//只有当前node成功获取到锁后才会跳出自旋
for (; ; ) {
Node pred = node.prev;
//只有当前节点是当前节点是head.next 才能尝试获取锁
if (pred == head && tryAcquire(arg)) {
//设置头结点
setHead(node);
//help GC
pred.next = null;
//抢到锁 直接return;
return;
}
//不符合抢锁条件 挂起当前线程
System.out.println("线程: " + Thread.currentThread().getName() + " .挂起");
LockSupport.park();
System.out.println("线程: " + Thread.currentThread().getName() + " .唤醒");
//什么时候唤醒被park的线程呢? unlock过程
}
}
private Node addWaiter() {
Thread thread = Thread.currentThread();
Node node = new Node(thread);
//队列中有元素
Node x = tail;
if (x != null) {
node.prev = x;
if (compareAndSetTail(x, node)) {
x.next = node;
return node;
}
}
//自旋入队(一定会成功入队)
enq(node);
return node;
}
private void enq(Node node) {
for (; ; ) {
if (tail == null) {
//补充节点成功 (这里的期望值是NULL)
if (compareAndSetHead(new Node())) {
tail = head;
}
} else {
//当前队列中刚已经有node了,需要CAS方式追加一个node
Node x = tail;
if (x != null) {
node.prev = x;
//CAS设置成功。
if (compareAndSetTail(x, node)) {
x.next = node;
//入队成功后直接return。
return;
}
}
}
}
}
private boolean tryAcquire(int arg) {
if (state == 0) {
if (!hasQueuedPredecessor() && compareAndSetState(0, arg)) {
//走到这里说明抢占锁成功了,需要将exclusiveOwnerThread设置为当前线程。
this.exclusiveOwnerThread = Thread.currentThread();
return true;
}
} else if (Thread.currentThread() == this.exclusiveOwnerThread) {
//计算state的下一个状态。
int c = getState() + arg;
this.state = c;
return true;
}
return false;
}
private boolean hasQueuedPredecessor() {
Node h = head;
Node t = tail;
Node s;
return h != t && ((s = h.next) == null || s.thread != Thread.currentThread());
}
@Override
public void unlock() {
release(1);
}
public void release(int arg) {
//条件成立 说明线程已经完全释放锁了,
if (tryRelease(arg)) {
Node head = this.head;
//唤醒head.next
if (head.next != null) {
unparkSuccessor(head);
}
}
}
//唤醒节点
private void unparkSuccessor(Node node) {
Node s = node.next;
if (s != null && s.thread != null) {
LockSupport.unpark(s.thread);
}
}
public boolean tryRelease(int arg) {
int c = getState() - arg;
//当先线程不是获取锁的线程 直接抛出异常
if (getExclusiveOwnerThread() != Thread.currentThread()) {
throw new RuntimeException("fuck you !!! must getLock");
}
//如果执行到这里存在并发吗? 不存在 只有一个线程(当前持有锁的线程)会来到这里
//c == 0,说明状态已经被完全释放了,
if (c == 0) {
//独占线程置为NULL
this.exclusiveOwnerThread = null;
//状态设置为0
this.state = 0;
return true;
}
//当前线程没有完全释放锁 (c != 0)
this.state = c;
return false;
}
private void setHead(Node node) {
this.head = node;
//因为当前节点已经是获取锁的线程了,直接将引用的thread属性置为NULL即可
node.thread = null;
//将前置节点也置为NULL。
node.prev = null;
}
private static final Unsafe unsafe;
private static final long stateOffset;
private static final long headOffset;
private static final long tailOffset;
static {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
unsafe = (Unsafe) f.get(null);
stateOffset = unsafe.objectFieldOffset
(MiniReentrantLock.class.getDeclaredField("state"));
headOffset = unsafe.objectFieldOffset
(MiniReentrantLock.class.getDeclaredField("head"));
tailOffset = unsafe.objectFieldOffset
(MiniReentrantLock.class.getDeclaredField("tail"));
} catch (Exception ex) {
throw new Error(ex);
}
}
private final boolean compareAndSetHead(Node update) {
return unsafe.compareAndSwapObject(this, headOffset, null, update);
}
private final boolean compareAndSetTail(Node expect, Node update) {
return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
public int getState() {
return state;
}
public Thread getExclusiveOwnerThread() {
return exclusiveOwnerThread;
}
public Node getHead() {
return head;
}
public Node getTail() {
return tail;
}
}



