【java并发编程的艺术读书笔记】AQS队列同步器简介、实现自定义锁

AQS介绍

AQSAbstractQueuedSynchronizer)是 Java 并发包(java.util.concurrent)中一个重要的基础类,用于实现同步器(Synchronizer)的框架。AQS 提供了一种基于 FIFO 等待队列的机制,使得开发者可以相对容易地实现各种自定义的同步组件,例如锁、信号量、倒计时门栓等。

AQS 主要是一个抽象类,它定义了一些基本的同步操作,而具体的同步逻辑需要子类继承并实现。AQS 内部维护了一个等待队列,用于管理等待获取同步状态的线程

AQS 的核心思想是,通过维护一个 state 变量来表示同步状态当 state 为 0 时表示没有线程占用资源当 state 大于 0 时表示资源已经被占用。具体的同步操作如锁的获取(acquire)和释放(release)等都是基于这个 state 变量来实现的。

AQS 提供了两种模式来实现同步组件独占模式(Exclusive mode)和共享模式(Shared mode)。

在独占模式下,只有一个线程可以获取同步状态,比如可重入锁(ReentrantLock);
在共享模式下多个线程可以同时获取同步状态,比如读写锁(ReentrantReadWriteLock)。

AQS的常用方法

  • getState():获取当前同步状态。
  • setState(int newState):设置当前同步状态。
  • compareAndSetState(int expect,int update):使用CAS设置当前状态,该方法能够保证状态
    设置的原子性。

继承AQS需要实现的方法

  • tryAcquire(int arg):尝试获取同步状态,成功返回 true,否则返回 false。

  • tryRelease(int arg):尝试释放同步状态。

  • tryAcquireShared(int arg):尝试以共享模式获取同步状态,成功返回一个大于 0 的值,表示可用资源数量,失败返回小于 0 的值。

  • tryReleaseShared(int arg):尝试以共享模式释放同步状态。

通过继承AQS来实现自定义锁

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class CustomLock {
    private final Sync sync = new Sync();

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

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

    private static class Sync extends AbstractQueuedSynchronizer {
        @Override
        protected boolean tryAcquire(int arg) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            if (getState() == 0) {
                throw new IllegalMonitorStateException("Lock not held");
            }
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }
    }

    public static void main(String[] args) {
        CustomLock customLock = new CustomLock();

        Runnable task = () -> {
            customLock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " has acquired the lock.");
                Thread.sleep(1000); // Simulating some work
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                customLock.unlock();
                System.out.println(Thread.currentThread().getName() + " has released the lock.");
            }
        };

        Thread thread1 = new Thread(task);
        Thread thread2 = new Thread(task);

        thread1.start();
        thread2.start();
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值