java-基于AQS实现锁

Posted AlbertXe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java-基于AQS实现锁相关的知识,希望对你有一定的参考价值。

java-基于AQS实现锁

AQS

是AbstractQueuedSynchronizer 抽象队列同步器

1.采用双向链表的数据结构,当多线程同时竞争锁的时候,第一个线程拿到锁后,后续的线程封装成Node节点依次进入同步队列进行排队等待。

2.AQS内部会采取自旋(死循环)的机制,一直判断头节点是否满足获取锁的条件,当锁被第一个线程释放后,队列中头节点条件满足(检查锁的状态是否为0),然后让头节点获取到锁,并脱离队列,如下图:

package me.ele.checkcenter.marketing.util.Test;

import org.jetbrains.annotations.NotNull;

import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * @author: 谢洪伟
 * 2021/6/25 11:40 上午
 */
public class MyLock implements Lock {
    private Sync sync = new Sync();

    private static class Sync extends AbstractQueuedSynchronizer{
        protected Sync() {
            super();
        }

        @Override
        protected boolean tryAcquire(int arg) {
            // cas比较内存中原始值0,则修改为传入的值
            if (compareAndSetState(0, arg)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            if (getState() == 0) {
                throw new UnsupportedOperationException();
            }
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        @Override
        protected int tryAcquireShared(int arg) {
            return super.tryAcquireShared(arg);
        }

        @Override
        protected boolean tryReleaseShared(int arg) {
            return super.tryReleaseShared(arg);
        }

        /**
         * 是否同步独占  true 已被独占  false 未被独占
         * @return
         */
        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        Condition newCondition() {
            return new ConditionObject();//AQS已经实现condition
        }

    }

    @Override
    public void lock() {
        sync.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, @NotNull TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1,unit.toNanos(time));
    }

    @Override
    public void unlock() {
        sync.release(1);
    }

    @NotNull
    @Override
    public Condition newCondition() {
        return sync.newCondition();
    }

    public static void main(String[] args) {
        MyLock lock = new MyLock();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                lock.lock();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                System.out.println("time="+new Date());
                lock.unlock();
            }).start();
        }
    }
}

以上是关于java-基于AQS实现锁的主要内容,如果未能解决你的问题,请参考以下文章

如何基于aqs实现一个锁

AQS

Java并发编程 JUC中的锁

从 synchronized 到 CAS 和 AQS - 彻底弄懂 Java 各种并发锁

同步队列器AQS的实现原理

Java锁机制4.0