栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

AQS源码解析1.前导

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

AQS源码解析1.前导

参考小刘讲源码

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;
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/631160.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号