ReentrantLock源码分析


本篇内容介绍了“ReentrantLock源码分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!从类图我们可以直观地了解到,ReentrantLock最终还是使用AQS来实现地,并且根据参数来决定其内部是一个公平????还是非公平锁????,默认是非公平锁????。其中Sync类直接继承自AQS,它的子类NonfairSync和FairSync分别实现了获取锁的非公平与公平策略。如果读者对AQS还不了解的话,可以去看看我的这篇文章:抽象同步队列AQS——AbstractQueuedSynchronizer锁详解在这里,AQS的state状态值表示线程获取该锁的可重入次数,在默认情况下,state的值为0表示当前锁没有被任何线程持有。当一个线程第一次获取该锁时,会尝试使用CAS设置state的值为1,如果CAS成功则当前线程获取了该锁,然后记录该锁的持有者为当前线程。在该线程没用释放锁的情况下第二次获取该锁后,状态值被设置为2,这就是可重入次数。在该线程释放锁时,会尝试使用CAS让状态值减1,如果减1后状态值为0,则当前线程释放该锁。lock()获取锁,其实就是把state从0变成n(重入锁可以累加)。实际调用的是sync的lock方法,分公平和非公平。在如上代码中,ReentrantLock的lock()委托给sync类,根据创建的ReentrantLock构造函数选择sync的实现是NonfairSync还是FairSync,先看看sync的子类NonfairSync(非公平锁????)的情况下面是AQS的acquire的核心源码之前说过,AQS并没有提供可用的tryAcquire方法,tryAcquire方法需要子类自己定制化,所以这里代码会调用ReentantLock重写的tryAcquire方法。我们看下非公平锁????的实现结束完非公平锁????的实现代码,回过头来看看非公平在这里是怎么体现的。首先非公平是说先尝试获取锁的线程并不一定比后尝试获取锁的线程优先获取锁????。而是使用了抢夺策略。那么下面我们看看公平锁????是怎么实现公平的。如上代码所示,公平的tryAcquire策略与非公平的类似,不同之处在于,代码在设置CAS操作之前添加了hasQueuedPredecessors()方法,该方法是实现公平性的核心代码。代码如下该方法与lock()方法类似,不同在于对中断进行响应,如果当前线程在调用该方法时,其它线程调用了当前线程的interrupt()方法,则该线程抛出异常而返回尝试获取锁,如果当前锁没用被其它线程持有,则当前线程获取该锁并返回true,否则返回false。注意,该方法不会引起当前线程阻塞如上代码与非公平锁的tryAcquire()方法代码类似,所以tryLock()使用的是非公平策略。尝试获取锁,与tryLock()的不同之处在于,它设置了超 香港云主机时时间,如果超时时间到了,没用获取到锁,则返回false,以下是相关代码尝试获取锁,如果当前线程持有锁,则调用该方法会让该线程持有的AQS状态值减1,如果减1后当前状态值为0,则当前线程会释放该锁,否则仅仅减1而已。如果当前线程没用持有该锁而调用了该方法则会抛出异常,代码如下:下面使用ReentrantLock来实现一个简单的线程安全的list集合如上代码在操作arrayList元素前进行加锁保证同一时间只有一个线程可用对arrayList数组进行修改,但是也只能一个线程对arrayList进行访问。如图,假如线程Thread-1,Thread-2,Thread-3同时尝试获取独占锁ReentrantLock,加上Thread-1获取到了????,则Thread-2和Thread-3就会被转换为Node节点并放入ReentrantLock对应的AQS阻塞队列,而后阻塞挂起。如图,假设Thread-1获取锁后调用了对应的锁创建的条件变量1,那么Thread-1就会释放获取到的????,然后当前线程就会被转换为Node节点插入条件变量1的条件队列。由于Thread-1释放了????,所以阻塞到AQS队列里面的Thread-2和Thread-3就会有机会获取到该锁,假如使用的是公平性策略,那么者时候Thread-2会获取到锁,从而从AQS队列里面移除Thread-2对应的Node节点。“ReentrantLock源码分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注开发云网站,小编将为大家输出更多高质量的实用文章!

相关推荐: 如何使用Java泛型方法

这篇“如何使用Java泛型方法”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何使用Java泛型方法”文章吧。一般定义如下,即方法的前面加了个三…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 08/15 17:08
下一篇 08/15 17:08

相关推荐