使用AQS重写锁

package com.zh.thread.aqs;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
 * 
 * @author zengHao
 *
 */
public class AqsLock implements Lock{
	private Helper helper = new Helper();
	
	/**
	 * 将子类定义为非公共内部帮助器类,
	 * 可用它们来实现其封闭类的同步属性
	 * @author zengHao
	 *
	 */
	private class Helper extends AbstractQueuedSynchronizer{
		@Override
		protected boolean tryAcquire(int arg) {
			//获取同步状态
			int state  = getState();
			Thread t = Thread.currentThread();
			//第一个线程进入,可拿到锁,返回true
			//第二个线程进入,则无法拿到锁,返回false。但如果当前进来的线程与保存的线程是同一线程,则可拿到锁,更新状态值
			if(state == 0) {
				if(compareAndSetState(0, arg)) {
					setExclusiveOwnerThread(Thread.currentThread());
					return true;
				}
				//当前进来的线程与保存的线程是同一线程(锁重入处理)
			}else if(getExclusiveOwnerThread() == t){
				setState(state + 1);
				return true; 
			}
			return false;
		}
		
		@Override
		protected boolean tryRelease(int arg) {
			//锁的获取与释放一一对应,如果不对应则抛出异常
			if(Thread.currentThread() != getExclusiveOwnerThread()) {
				throw new RuntimeException();
			}
			//获取状态-1,
			int state = getState()-arg;
			boolean flag = false;
			//当state等于0时,表示所有重入锁均已释放
			if(state == 0) { 
				//清空
				setExclusiveOwnerThread(null);
				flag = true;
			}
			//当state不等于0时,还是设置为之前的状态
			setState(state);
			return flag;
		}
		
		Condition newCondition() {
			return new ConditionObject();
		}
	}
	
	
	@Override
	public void lock() {
		helper.acquire(1);
		
	}

	@Override
	public void lockInterruptibly() throws InterruptedException {
		helper.acquireInterruptibly(1);
	}

	@Override
	public boolean tryLock() {
		
		return helper.tryAcquire(1);
	}

	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		return helper.tryAcquireNanos(1, unit.toNanos(time));
	}

	@Override
	public void unlock() {
		helper.release(1);
	}

	@Override
	public Condition newCondition() {
		return helper.newCondition();
	}
}

测试:

package com.zh.thread.lock;


import com.zh.thread.aqs.AqsLock;
public class Sequence2 {
    private int value;
    private AqsLock lock = new AqsLock();
    public void a() {
        lock.lock();
        System.err.println("a");
        b();
        lock.unlock();
    }
    
    public void b() {
        lock.lock();
        System.err.println("b");
        lock.unlock();
    }
    public static void main(String[] args) {
        Sequence2 sequence = new Sequence2();
        new Thread(new Runnable() {
            @Override
            public void run() {
                sequence.a();
            }
        }).start();
        
    }
}
结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值