java 使用AQS写可重入锁

本文介绍如何使用 Java 的 AbstractQueuedSynchronizer (AQS) 实现一个可重入锁 MyLock2。通过自定义 Sync 类并覆盖 tryAcquire 和 tryRelease 方法,实现了锁的基本功能。此外,还提供了条件变量的支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java 使用AQS写可重入锁

在上一篇文章中,手动实现了一个可重入锁,在本节中,使用AQS重写这个可重入锁MyLock2类,实现了Lock接口,定义内部类Sync继承自AbstractQueuedSynchronizer,并实现了两个方法,分别为tryAcquire(int arg)和tryRelease(int arg),tryAcquire函数的实现逻辑与上一篇文章"java 手动实现一个可重入锁"中的lock函数一致,而tryRelease函数的实现逻辑与unlock一致。下面给出实现代码,具体的流程见代码注释

package com.concur.class23;

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

public class MyLock2 implements Lock{
	
    private Sync sync=new Sync();
    
	private class Sync extends AbstractQueuedSynchronizer{
		@Override
		protected boolean tryAcquire(int arg) {
			//当目前并没有线程获得锁时,进来的线程就可以拿到锁,因此返回true
			//当有其他线程进来时,1.当前进来的线程和当前保存的线程是同一个线程,则可以拿到锁,但是需要更新状态值 2.若与当前保存的线程
			//不是同一个线程,则拿不到锁,返回false
		    int state=getState();
		    Thread t=Thread.currentThread();
		    //若当前并没有线程获得锁,state=0
		    if(state==0){
		    	//将state的值更新
		    	if(compareAndSetState(0, arg)){
		    		//设置当前独占线程为t
		    		setExclusiveOwnerThread(t);
		    		return true;
		    	}
		    }
		    //若当前想要获得锁的线程已经获得锁,即可重入
		    else if(getExclusiveOwnerThread()==t){
		    	setState(state+arg);
		    	return true;
		    }
		    return false;
			
		}
		@Override
		protected boolean tryRelease(int arg) {
			//若当前想要释放锁的线程不是保存的线程,则抛出异常
			if(getExclusiveOwnerThread()!=getExclusiveOwnerThread()){
				throw new RuntimeException();
			}
			int state=getState()-arg;
			boolean flag=false;
			//若state为0,则表明当前没有线程持有锁,则设置为null
			if(state==0){
				setExclusiveOwnerThread(null);
				flag=true;
			}
			setState(state);
			return flag;
		}
		Condition newCondition(){
			return new ConditionObject();
		}
	}
	@Override
	public void lock() {	
		sync.acquire(1);
	}
	

	@Override
	public void unlock() {
        sync.release(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 Condition newCondition() {
		return sync.newCondition();
	}

}

编写测试类Test用来测试该可重入锁:

package com.concur.class23;

public class Test {
	  MyLock2 lock=new MyLock2();
      public void a(){
    	  lock.lock();
    	  System.out.println("a");
    	  b();
    	  lock.unlock();
      }
      public void b(){
    	  lock.lock();
    	  System.out.println("b");
    	  lock.unlock();
      }
      public static void main(String[] args) {
		Test t=new Test();
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				t.a();
			}
		}).start();
	}
}

输出结果为:

a
b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值