主要的 AQS 方法

本文介绍了Java中的AQS框架,重点讲解了其在实现同步器、锁(如ReentrantLock)、独占与共享模式以及状态管理方面的核心方法。通过实例演示了如何使用AQS创建自定义独占锁,以及线程间的互斥和同步行为。
摘要由CSDN通过智能技术生成

AQS(AbstractQueuedSynchronizer)是Java中用于实现同步器的框架,位于java.util.concurrent.locks包下。它提供了一种灵活且强大的方式来实现各种同步机制,例如锁、计数器、信号量等。AQS的设计基于FIFO(先进先出)等待队列,通过内部的状态来管理线程的获取和释放锁的操作。

acquire(int arg):

用于独占模式,当线程尝试获取锁时调用。arg参数是一个用于表示状态的值。

release(int arg):

用于独占模式,当线程释放锁时调用。arg参数是一个用于表示状态的值。

acquireShared(int arg):

用于共享模式,当线程尝试获取共享资源时调用。arg参数也是一个用于表示状态的值。

releaseShared(int arg):

用于共享模式,当线程释放共享资源时调用。arg参数是一个用于表示状态的值。

tryAcquire(int arg):

尝试以独占模式获取同步状态,成功返回true,失败返回false。

tryRelease(int arg):

尝试以独占模式释放同步状态,成功返回true,失败返回false。

tryAcquireShared(int arg):

尝试以共享模式获取同步状态,成功返回true,失败返回false。

tryReleaseShared(int arg):

尝试以共享模式释放同步状态,成功返回true,失败返回false。

isHeldExclusively():

查询当前同步器是否在独占模式下被当前线程所持有。

AQS中,同步状态(state)的含义由具体的同步器决定。通常情况下,0 表示未被锁定状态,1 或者其他非零值表示已经被锁定状态。

在独占锁的情况下,常见的含义是:

  • 0(未锁定):表示资源没有被线程占用,可以被当前线程或其他线程获取。

  • 1(已锁定):表示资源已经被某个线程独占,其他线程无法获取,必须等待释放。

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AQSStateExample {
    private static Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        // 同步状态为0表示未锁定
        System.out.println("Lock state before acquisition: " + ((ReentrantLock) lock).getHoldCount());
        
        // 尝试获取锁,同步状态变为1
        lock.lock();
        try {
            System.out.println("Lock state after acquisition: " + ((ReentrantLock) lock).getHoldCount());
        } finally {
            // 释放锁,同步状态变为0
            lock.unlock();
            System.out.println("Lock state after release: " + ((ReentrantLock) lock).getHoldCount());
        }
    }
}

在这个例子中,getHoldCount 方法用于获取当前线程保持锁的次数。在未获取锁时,同步状态为0。在获取锁后,同步状态变为1。在释放锁后,同步状态重新变为0。

以下是创建一个简单的独占锁,允许一个线程独占资源,其他线程必须等待。

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

class MyExclusiveLock {

    private final Sync sync = new Sync();

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

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

    private static class Sync extends AbstractQueuedSynchronizer {
        // 实现 AQS 的抽象方法

        @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();
            }
            // 释放锁
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        @Override
        protected boolean isHeldExclusively() {
            // 判断当前线程是否持有锁
            return getExclusiveOwnerThread() == Thread.currentThread();
        }
    }
}

public class AQSExample {

    public static void main(String[] args) {
        MyExclusiveLock myLock = new MyExclusiveLock();

        // 线程1获取锁
        new Thread(() -> {
            myLock.lock();
            try {
                System.out.println("Thread 1 acquired the lock.");
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                myLock.unlock();
                System.out.println("Thread 1 released the lock.");
            }
        }).start();

        // 线程2尝试获取锁(会被阻塞)
        new Thread(() -> {
            myLock.lock();
            try {
                System.out.println("Thread 2 acquired the lock.");
            } finally {
                myLock.unlock();
                System.out.println("Thread 2 released the lock.");
            }
        }).start();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值