当前位置: 首页 > news >正文

河北智能网站建设多少钱上海杨浦区建设网站

河北智能网站建设多少钱,上海杨浦区建设网站,做网站企业经营范围,黄页官网JUC第十三讲#xff1a;JUC锁: ReentrantLock详解 本文是JUC第十三讲#xff0c;JUC锁#xff1a;ReentrantLock详解。可重入锁 ReentrantLock 的底层是通过 AbstractQueuedSynchronizer 实现#xff0c;所以先要学习上一章节 AbstractQueuedSynchronizer 详解。 文章目录 …JUC第十三讲JUC锁: ReentrantLock详解 本文是JUC第十三讲JUC锁ReentrantLock详解。可重入锁 ReentrantLock 的底层是通过 AbstractQueuedSynchronizer 实现所以先要学习上一章节 AbstractQueuedSynchronizer 详解。 文章目录 JUC第十三讲JUC锁: ReentrantLock详解1、带着BAT大厂的面试问题去理解2、ReentrantLock源码分析2.1、类的继承关系2.2、类的内部类2.3、类的属性2.4、类的构造函数2.5、核心函数分析 3、示例分析3.1、公平锁 4、参考文章 1、带着BAT大厂的面试问题去理解 请带着这些问题继续后文会很大程度上帮助你更好的理解相关知识点。 什么是可重入什么是可重入锁? 它用来解决什么问题? 一定程度避免死锁ReentrantLock的核心是AQS那么它怎么来实现的继承吗? 说说其类内部结构关系。独占模式ReentrantLock是如何实现公平锁的?ReentrantLock是如何实现非公平锁的?ReentrantLock默认实现的是公平还是非公平锁? 非公平使用ReentrantLock实现公平和非公平锁的示例?ReentrantLock和Synchronized的对比? 2、ReentrantLock源码分析 2.1、类的继承关系 ReentrantLock实现了Lock接口Lock接口中定义了lock与unlock相关操作并且还存在newCondition方法表示生成一个条件。 public class ReentrantLock implements Lock, java.io.Serializable2.2、类的内部类 ReentrantLock总共有三个内部类并且三个内部类是紧密相关的下面先看三个类的关系。 说明ReentrantLock类内部总共存在Sync、NonfairSync、FairSync三个类NonfairSync与FairSync类继承自Sync类Sync类继承自 AbstractQueuedSynchronizer 抽象类。下面逐个进行分析。 Sync类 Sync类的源码如下: abstract static class Sync extends AbstractQueuedSynchronizer {// 序列号private static final long serialVersionUID -5179523762034025860L;// 获取锁abstract void lock();// 非公平方式获取final boolean nonfairTryAcquire(int acquires) {// 当前线程final Thread current Thread.currentThread();// 获取状态int c getState();// 表示没有线程正在竞争该锁if (c 0) {// 比较并设置状态成功状态0表示锁没有被占用if (compareAndSetState(0, acquires)) {// 设置当前线程独占setExclusiveOwnerThread(current); return true; // 成功}}// 当前线程拥有该锁else if (current getExclusiveOwnerThread()) {// 增加重入次数int nextc c acquires; if (nextc 0) // overflowthrow new Error(Maximum lock count exceeded);// 设置状态setState(nextc); // 成功return true; }// 失败return false;}// 实现AQS提供的拓展点// 试图在共享模式下获取对象状态此方法应该查询是否允许它在共享模式下获取对象状态如果允许则获取它protected final boolean tryRelease(int releases) {int c getState() - releases;// 当前线程不为独占线程if (Thread.currentThread() ! getExclusiveOwnerThread())throw new IllegalMonitorStateException(); // 抛出异常// 释放标识boolean free false; if (c 0) {free true;// 已经释放清空独占setExclusiveOwnerThread(null); }// 设置标识setState(c); return free; }// 判断资源是否被当前线程占有protected final boolean isHeldExclusively() {// While we must in general read state before owner,// we dont need to do so to check if current thread is ownerreturn getExclusiveOwnerThread() Thread.currentThread();}// 新生一个条件final ConditionObject newCondition() {return new ConditionObject();}// Methods relayed from outer class// 返回资源的占用线程final Thread getOwner() {return getState() 0 ? null : getExclusiveOwnerThread();}// 返回状态final int getHoldCount() {return isHeldExclusively() ? getState() : 0;}// 资源是否被占用final boolean isLocked() {return getState() ! 0;}/*** Reconstitutes the instance from a stream (that is, deserializes it).*/// 自定义反序列化逻辑private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {s.defaultReadObject();setState(0); // reset to unlocked state} }  Sync类存在如下方法和作用如下。 NonfairSync类 NonfairSync类继承了Sync类表示采用非公平策略获取锁其实现了Sync类中抽象的lock方法源码如下 // 非公平锁 static final class NonfairSync extends Sync {// 版本号private static final long serialVersionUID 7316153563782823691L;// 获得锁final void lock() {// 比较并设置状态成功状态0表示锁没有被占用if (compareAndSetState(0, 1))// 把当前线程设置独占了锁setExclusiveOwnerThread(Thread.currentThread());else // 锁已经被占用或者set失败// 以独占模式获取对象忽略中断acquire(1);}protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);} }说明从lock方法的源码可知每一次都尝试获取锁而并不会按照公平等待的原则进行等待让等待时间最久的线程获得锁。 FairSync类 FairSync类也继承了Sync类表示采用公平策略获取锁其实现了Sync类中的抽象lock方法源码如下 // 公平锁 static final class FairSync extends Sync {// 版本序列化private static final long serialVersionUID -3000897897090466540L;final void lock() {// 以独占模式获取对象忽略中断acquire(1);}/*** Fair version of tryAcquire. Dont grant access unless* recursive call or no waiters or is first.*/// 尝试公平获取锁 AQS抽象类提供的拓展点protected final boolean tryAcquire(int acquires) {// 获取当前线程final Thread current Thread.currentThread();// 获取状态int c getState();if (c 0) { // 状态为0// 不存在已经等待更久的线程 并且比较并且设置状态成功if (!hasQueuedPredecessors() compareAndSetState(0, acquires)) {// 设置当前线程独占setExclusiveOwnerThread(current);return true;}}// 状态不为0即资源已经被线程占据else if (current getExclusiveOwnerThread()) {// 下一个状态int nextc c acquires;if (nextc 0) // 超过了int的表示范围throw new Error(Maximum lock count exceeded);// 设置状态setState(nextc);return true;}return false;} }说明跟踪lock方法的源码可知当资源空闲时它总是会先判断sync队列AbstractQueuedSynchronizer中的数据结构是否有等待时间更长的线程如果存在则将该线程加入到等待队列的尾部实现了公平获取原则。其中FairSync类的lock的方法调用如下只给出了主要的方法。 说明可以看出只要资源被其他线程占用该线程就会添加到sync queue中的尾部而不会先尝试获取资源。这也是和Nonfair最大的区别Nonfair每一次都会尝试去获取资源如果此时该资源恰好被释放则会被当前线程获取这就造成了不公平的现象当获取不成功再加入队列尾部。 2.3、类的属性 ReentrantLock类的sync非常重要对 ReentrantLock 类的操作大部分都直接转化为对Sync和 AbstractQueuedSynchronizer 类的操作。 public class ReentrantLock implements Lock, java.io.Serializable {// 序列号private static final long serialVersionUID 7373984872572414699L; // 同步队列private final Sync sync; }2.4、类的构造函数 ReentrantLock() 型构造函数 默认是采用的非公平策略获取锁 public ReentrantLock() {// 默认非公平策略sync new NonfairSync(); }ReentrantLock(boolean) 型构造函数 可以传递参数确定采用公平策略或者是非公平策略参数为true表示公平策略否则采用非公平策略: public ReentrantLock(boolean fair) {sync fair ? new FairSync() : new NonfairSync(); }2.5、核心函数分析 通过分析ReentrantLock的源码可知对其操作都转化为对Sync对象的操作由于Sync继承了AQS所以基本上都可以转化为对AQS的操作。如将ReentrantLock的lock函数转化为对Sync的lock函数的调用而具体会根据采用的策略(如公平策略或者非公平策略)的不同而调用到Sync的不同子类。 所以可知在ReentrantLock的背后是AQS对其服务提供了支持由于之前我们分析AQS的核心源码遂不再累赘。下面还是通过例子来更进一步分析源码。 3、示例分析 3.1、公平锁 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;class MyThread extends Thread {private Lock lock;public MyThread(String name, Lock lock) {super(name);this.lock lock;}public void run () {lock.lock();try {System.out.println(Thread.currentThread() running);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}} finally {lock.unlock();}} }public class AbstractQueuedSynchronizerDemo {public static void main(String[] args) throws InterruptedException {Lock lock new ReentrantLock(true);MyThread t1 new MyThread(t1, lock); MyThread t2 new MyThread(t2, lock);MyThread t3 new MyThread(t3, lock);t1.start();t2.start(); t3.start();} }运行结果(某一次): Thread[t1,5,main] running Thread[t2,5,main] running Thread[t3,5,main] running说明: 该示例使用的是公平策略由结果可知可能会存在如下一种时序。 说明: 首先t1线程的lock操作 - t2线程的lock操作 - t3线程的lock操作 - t1线程的unlock操作 - t2线程的unlock操作 - t3线程的unlock操作。根据这个时序图来进一步分析源码的工作流程。 t1线程执行lock.lock下图给出了方法调用中的主要方法。 说明: 由调用流程可知t1线程成功获取了资源可以继续执行。 t2线程执行 lock.lock下图给出了方法调用中的主要方法。 说明: 由上图可知最后的结果是t2线程会被禁止因为调用了LockSupport.park。 t3线程执行lock.lock下图给出了方法调用中的主要方法。 说明由上图可知最后的结果是t3线程会被禁止因为调用了LockSupport.park。 t1线程调用了lock.unlock下图给出了方法调用中的主要方法。 说明如上图所示最后head的状态会变为0t2线程会被unpark即t2线程可以继续运行。此时t3线程还是被禁止。 t2获得cpu资源继续运行由于t2之前被park了现在需要恢复之前的状态下图给出了方法调用中的主要方法。 说明在setHead函数中会将head设置为之前head的下一个结点并且将pre域与thread域都设置为null在acquireQueued返回之前sync queue就只有两个结点了。 t2执行lock.unlock下图给出了方法调用中的主要方法。 说明: 由上图可知最终unpark t3线程让t3线程可以继续运行。 t3线程获取cpu资源恢复之前的状态继续运行。 说明: 最终达到的状态是sync queue中只剩下了一个结点并且该节点除了状态为0外其余均为null。 t3执行lock.unlock下图给出了方法调用中的主要方法。 说明: 最后的状态和之前的状态是一样的队列中有一个空节点头节点为尾节点均指向它。 使用公平策略和Condition的情况可以参考上一篇关于AQS的源码示例分析部分不再累赘。 4、参考文章 【JUC】JDK1.8源码分析之ReentrantLock三
http://www.w-s-a.com/news/594231/

相关文章:

  • 运动鞋建设网站前的市场分析wordpress 搜索框代码
  • app开发网站开发教程平台网站开发的税率
  • 百度网站优化排名加强服务保障满足群众急需i
  • 宁夏建设职业技术学院网站安徽网站优化建设
  • 四川关于工程建设网站硬盘做网站空间
  • 桂林网站制作培训学校外包seo公司
  • 莱州网站建设方案北京装修公司口碑
  • 大型网站建设济南兴田德润团队怎么样韩国女足出线了吗
  • 南通做网站找谁重庆网络推广网站推广
  • ps网站主页按钮怎么做怎样做网站的用户分析
  • 哪个网站做黑色星期五订酒店活动公司网络营销推广软件
  • 岳阳新网网站建设有限公司网页设计基础考试题目
  • 辽宁响应式网站费用海外平台有哪些
  • 杨凌规划建设局网站网站后台建设怎么进入
  • 有赞商城网站建设企业管理咨询是做什么的
  • 提供衡水网站建设中国石化工程建设有限公司邮政编码
  • 大芬地铁站附近做网站工业设计公司报价
  • 建设网站最强永年网站建设
  • 网站分站代理加盟wordpress国内工作室主题
  • 东营远见网站建设公司服装网站建设内容
  • 互助平台网站建设费用百度seo优化怎么做
  • lol英雄介绍网站模板工商局网上注册
  • 电商网站运营策划什么样的网站容易做seo
  • 网站备案需要什么流程怎么创建小程序卖东西
  • 陇西网站建设 室内设计持啊传媒企业推广
  • 连云港做网站制作首选公司如何让单位网站做防护
  • wordpress企业网站源码开发网站用什么工具做设计
  • 网站负责人不是法人seo神马网站推广器
  • 网站建设绩效考核方案wordpress支付宝付款
  • 高要区住房和城乡建设局网站如何网上注销自己的公司