AQS简介和AQS案例

目录

AQS是什么?有什么用

特点:

和synchronized有什么不同?

ReenTrantLock和synchronized有什么区别

怎么利用AQS设计自己的锁?

关于Java并发编程 ,可参见gitee项目:


AQS是什么?有什么用

全称是 AbstractQueuedSynchronizer, 抽象队列同步器的意思, 是阻塞式锁和相关的同步器工具的框架。
阻塞式锁:多个线程同时调用同一个方法的时候,所有线程都被排队处理了。让线程进入阻塞状态进行等待,当获得相应的信号(唤醒,时间) 时,才可以进入线程的准备就绪状态,准备就绪状态的所有线程,通过竞争,进入运行状态。
非阻塞式锁:多个线程同时调用一个方法的时候,当某一个线程最先获取到锁,这时其他线程判断没拿到锁,这时就直接返回,只有当最先获取到锁的线程释放,其他线程才能进来,在它释放之前其它线程都会获取失败。

特点:

state 属性来表示资源的状态(分独占模式和共享模式),子类需要定义如何维护这个状态,控制如何获取

锁和释放锁

getState - 获取 state 状态
setState - 设置 state 状态
compareAndSetState - cas 机制设置 state 状态
独占模式是只有一个线程能够访问资源,而共享模式可以允许多个线程访问资源
提供了基于 FIFO 的等待队列,类似于 Monitor EntryList
条件变量来实现等待、唤醒机制,支持多个条件变量,类似于 Monitor WaitSet

和synchronized有什么不同?

首先你可以根据 aqs去设计自己的锁,设计出的锁可以是公平锁,而synchronized只能是非公平锁。而且当线程抢不到锁阻塞等待时可以被打断。

ReenTrantLock和synchronized有什么区别

1.使用区别
 Lock是一个接口,而synchronized是关键字,是内置的语言实现。

2.功能区别

(1)可中断锁:体现在lockInterruptibly()方法。如果线程A正在执行锁中代码,线程B正在等待获取该锁,时间太长了,B收到通知不用等了,它就可以中断自己,停止工作了。
(2)锁申请等待限时:体现在tryLock()方法上。
(3)公平锁:ReentrantLock可以实现公平锁,构造函数有一 public ReentrantLock(boolean fair),为true时使用公平锁。
(4)读写锁:读写锁将对一个资源的访问分为两个锁,一个读锁,一个写锁,从而使得读读不互斥,读写互斥以及写写互斥,提高性能。ReadWriteLock就是读写锁,是一个接口,ReentrantReadWriteLock实现了这个接口。可以通过readLock()获取读锁,writeLock()获取写锁。
(5)绑定多个条件:一个ReentrantLock可以绑定多个Condition对象,仅需多次调用new Condition()即可。而在synchronized中锁对象的wait()、notify()/notifyAll()可以实现一个隐含的条件,如果要和多余的条件关联,就不得不使用多个锁。
————————————————
版权声明:本文为CSDN博主「loser与你」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43559950/article/details/120075838

怎么利用AQS设计自己的锁?

设计一个不可重入的独占锁:

package TestAQSDemo;

import lombok.extern.slf4j.Slf4j;

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

import static ZBasic.Utils.Sleeper.sleep;


@Slf4j(topic = "c.TestAqs")
public class TestAqs {
    public static void main(String[] args) {
        MyLock lock = new MyLock();
        new Thread(() -> {
            lock.lock();
            try {
                log.debug("locking...");
                sleep(1);
            } finally {
                log.debug("unlocking...");
                lock.unlock();
            }
        },"t1").start();

        new Thread(() -> {
            lock.lock();
            try {
                log.debug("locking...");
            } finally {
                log.debug("unlocking...");
                lock.unlock();
            }
        },"t2").start();
    }
}

// 自定义锁(不可重入锁)
class MyLock implements Lock {

    // 独占锁  同步器类
    class MySync extends AbstractQueuedSynchronizer {
        @Override
        protected boolean tryAcquire(int arg) {
            if(compareAndSetState(0, 1)) {
                // 加上了锁,并设置 owner 为当前线程
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        @Override // 是否持有独占锁
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        public Condition newCondition() {
            return new ConditionObject();
        }
    }

    private MySync sync = new MySync();

    @Override // 加锁(不成功会进入等待队列) acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
    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, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(time));
    }

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

    @Override // 创建条件变量
    public Condition newCondition() {
        return sync.newCondition();
    }
}

参考:

黑马JUC

关于Java并发编程 ,可参见gitee项目:

https://gitee.com/trigger333/art-concurrent-book-plus

里面代码主要来自黑马JUC 和 《并发编程的艺术》,我也补充了一些代码,帮助初学者更好的理解和掌握Java JUC.

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

trigger333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值