【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();
    }
}

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

你可能感兴趣的:(读书笔记,java,开发语言,并发编程,AQS,自定义锁)