手写实现简单AQS

手写简单的AQS

参考,推荐学习 B站up:学java的基尔兽

package org.example.aqs;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;

public class MyLock {

    AtomicBoolean flag = new AtomicBoolean(false);

    Thread owner = null;

    AtomicReference<Node> head = new AtomicReference<>(new Node());

    AtomicReference<Node> tail = new AtomicReference<>(head.get());

    void lock(){
        if(flag.compareAndSet(false, true)){
            owner = Thread.currentThread();
            return;
        }
        Node current = new Node();
        current.thread = Thread.currentThread();
        while (true){
            Node currentTail = tail.get();
            if (tail.compareAndSet(currentTail, current)) {
                current.pre = currentTail;
                currentTail.next = current;
                break;
            }
        }
        while (true){
            // head --> A --> B --> C
            // 加入到尾节点后,先判断一下能否拿到锁,再park
            // 不然可能出现没有人再唤醒的情况
            if(current.pre == head.get() && flag.compareAndSet(false, true)){
                owner = Thread.currentThread();
                head.set(current);
                current.pre.next = null;
                current.pre = null;
                return;
            }
            LockSupport.park();
        }

    }

    void unlock(){
        if(this.owner != Thread.currentThread()){
            throw new IllegalStateException("The thread is not owned by this lock");
        }
        // head --> A
        Node headNode = head.get();
        Node next = headNode.next;
        flag.set(false);
        // 锁释放了
        if(next != null) {
            LockSupport.unpark(next.thread);
        }
    }

    class Node{
        Node pre;
        Node next;
        Thread thread;
    }
}
posted @ 2025-02-16 17:42  chendsome  阅读(14)  评论(0)    收藏  举报