手写一个ReentrantLock锁

本文介绍了作者在学习Java锁知识后,尝试手写ReentrantLock的心得。文中详细阐述了可重入锁与不可重入锁的原理,以及公平锁与非公平锁的区别。在实现过程中,作者特别提到了在创建可重入锁时遇到的问题及其解决方案,强调了修改owner和count的顺序对于正确实现重入的重要性。
摘要由CSDN通过智能技术生成

手写ReentrantLock

最近学习了Java语言中锁相关知识,看了一下ReentrantLock源码,自己手写了一个ReentrantLock

ReentrantLock是一个可重入锁,并且在源码中通过构造函数可以使其在公平锁和非公平锁之间转换。

可重入锁即当前线程可以在不释放锁的情况下多次获取锁,但是释放锁的次数应与获取锁的次数相同,否则会抛出IllegalMonitorStateException异常。

公平锁和非公平锁的区别在与,公平锁使先进入等待队列的线程先获取锁,每个线程都有机会获取锁。非公平锁则是每个线程获取锁的几率不确定,非公平锁并发性较好,但容易造成某些线程长时间获取不到锁。

不可重入ReentrantLock,非公平
/**
 * 不可重入锁
 */
public class WonderReentranrLock{
   
    //标记获取锁的线程,原子类型的引用保证原子性
    private AtomicReference<Thread> owner = new AtomicReference<>();
    //抢锁失败时进入等待队列
    private Queue<Thread> waitQueue = new LinkedBlockingQueue();

    /**
     * 加锁
     */
    public void lock(){
   
        //抢锁失败
        if(!tryLock()){
   
            Thread current = Thread.currentThread();
            //线程进入等待队列
            waitQueue.offer(current);
            //继续尝试抢锁
            for(;;){
   
                //获取队列头部
                Thread head = waitQueue.peek();
                //如果当前线程在队列头部
                if(current == head){
   
                    //抢锁
                    if(!tryLock()){
   
                        //如果抢锁失败
                        LockSupport.park();
                    }else{
   
                        //如果抢锁成功,线程出队列
                        waitQueue.poll();
                        return;
                    }
                }else{
   
                    //如果不在队列头部,将线程挂起
                    LockSupport.park();
                }
            }
        }
        //成功则抢到了锁
    }

    /**
     * 尝试加锁
     * @return
     */
    public boolean tryLock(){
   
        Thread current = Thread.currentThread
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值