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

购物网站制作流程百度seo找哪里

购物网站制作流程,百度seo找哪里,长沙做网站大概多少钱,网站组成费用本文是自己的学习笔记,主要参考资料如下 JavaSE文档 1、AQS 概述1.1、锁的原理1.2、任务队列1.2.1、结点的状态变化 1.3、加锁和解锁的简单流程 2、ReentrantLock2.1、加锁源码分析2.1.1、tryAcquire()的具体实现2.1.2、acquirQueued()的具体实现2.1.3、tryLock的具…

本文是自己的学习笔记,主要参考资料如下
JavaSE文档


  • 1、AQS 概述
    • 1.1、锁的原理
    • 1.2、任务队列
      • 1.2.1、结点的状态变化
    • 1.3、加锁和解锁的简单流程
  • 2、ReentrantLock
    • 2.1、加锁源码分析
      • 2.1.1、tryAcquire()的具体实现
      • 2.1.2、acquirQueued()的具体实现
      • 2.1.3、tryLock的具体实现
      • 2.1.5、总结

1、AQS 概述

1.1、锁的原理

AQS是指抽象类AbstractQueuedSynchronizer。这个抽象类代表着一种实现并发的方式。

具体实现方式是使用volitile修饰state变量,保证了state的可见性和有序性。最后使用CAS改变state的值,保证原子性。

那么AbstractQueuedSynchronizer通过更新state的值来实现的加锁和解锁。

下面是关键源代码的截图。
请添加图片描述
请添加图片描述


1.2、任务队列

AQS中维护了一个任务队列,是一个双向队列。队列节点是内部类Node

Node中记录者节点的状态waitStatus,比如CANCELSIGNAL等分别表示该任务节点已经取消和任务节点正在沉睡需要被唤醒。

当然,因为是双向列表所以也有指向前后节点的指针。下面是Node源码的部分截图。
请添加图片描述

这个队列会初始化一个头结点和一个尾结点作为虚拟节点。头结点的状态在整个加锁和释放锁的过程中都会变化。

1.2.1、结点的状态变化

当头结点指向的Node才拥有锁。

这里主要介绍三个状态

  • 0, 表示当前Node后续无节点在排队。不表明是否拥有锁。
  • -1,表示除了当前Node在排队以外,还有其他Node排在当前Node后面。不表明是否拥有锁。
  • 1,表示当前Node可能因为等待时间太长而放弃获取锁。

下面是三个Node在队列中的状态。这里从左到右解释他们的状态。
请添加图片描述
head指向第一个Node,所以当前Node拥有锁。

第一个NodewaitStatus=-1表示后续有节点等待获取锁。当该节点释放锁时会唤醒后续的节点。

第二个NodewaitStatus = -1,后续有节点等待获取锁。

第三个NodewaitStatus = 0,后续无节点等待获取锁。

1.3、加锁和解锁的简单流程

假设有两个线程A和B,他们需要争夺基于AQS实现的锁,下面是争夺的简单流程。

  1. 线程A先执行CAS,将state从0修改为1,线程A就获取到了锁资源,去执行业务代码即可。
  2. 线程B再执行CAS,发现state已经是1了,无法获取到锁资源。
  3. 线程B需要去排队,将自己封装为Node对象。
  4. 需要将当前B线程的Node放到双向队列保存,排队。

2、ReentrantLock

2.1、加锁源码分析

ReentrantLock分为公平锁和非公平锁。在加锁的时候因这两种锁的不同会有不同的加锁方式。

ReentrantLock默认是非公平锁,构造方法中传入false则是公平锁。

非公平锁的lock()方法会直接基于CAS尝试获取锁,如果成功的话则执行setExclusiveOwnerThread()方法表示当前线程持有该锁;如果失败则执行acquire()方法。

公平锁则是直接执行acquire()方法。下面是源码对比。
请添加图片描述
接下来的重点则是看acquire()的具体操作。

tryAcquire()方法会再次尝试获取锁,如果成功返回true,否则返回false

可以看到如果失败的话则将请求放到等待队列中同时发送中断信号。
在这里插入图片描述

2.1.1、tryAcquire()的具体实现

  • 非公平锁
    非公平锁会尝试再次直接通过CAS获取锁资源。因为是可重入锁,所以当锁的持有者是当前线程时也可直接获取锁,然后计数器加一。
    请添加图片描述

  • 公平锁
    公平锁的逻辑与非公平锁类似,只不过再获取锁之前会先判断AQS中自己是不是排在第一位,之后才会获取锁。
    请添加图片描述

2.1.2、acquirQueued()的具体实现

在这里插入图片描述
tryAcquire()返回false,即获取锁失败,就开始尝试将当前线程封装成Node节点插入到AQS的结尾。

在插入时我们会看到if(p == head && tryAcquire(arg))这样的语句。

这是因为AQS有伪头结点,所以当这个线程插入到AQS中时发现自己的上一个节点是头结点,即自己排在第一位,那无论是公平锁还是非公平锁自己都可以再次测试获取锁。所以会再次执行tryAcquire()

final boolean acquireQueued(final Node node, int arg) {// 不考虑中断// failed:获取锁资源是否失败(这里简单掌握落地,真正触发的,还是tryLock和lockInterruptibly)boolean failed = true;try {boolean interrupted = false;for (;;) {// 拿到当前节点的前继节点final Node p = node.predecessor();// 前继节点是否是head,如果是head,再次执行tryAcquire尝试获取锁资源。if (p == head && tryAcquire(arg)) {// 获取锁资源成功setHead(node);p.next = null; // 获取锁失败标识为falsefailed = false;return interrupted;}// 没拿到锁资源……// shouldParkAfterFailedAcquire:基于上一个节点转改来判断当前节点是否能够挂起线程,如果可以返回true,// 如果不能,就返回false,继续下次循环if (shouldParkAfterFailedAcquire(p, node) &&// 这里基于Unsafe类的park方法,将当前线程挂起parkAndCheckInterrupt())interrupted = true;}} finally {if (failed)// 在lock方法中,基本不会执行。cancelAcquire(node);}
}

2.1.3、tryLock的具体实现

无参的tryLock()比较简单,和tryAcquire()基本没区别。

这里主要讲解有参的tryAcquireNanos(int arg, long nanosTimeout)

它的作用在一个时间内尝试获得锁。在这个时间内没有获得锁会挂起park线程。如果成功则返回true,时间结束还没有获得则返回false

public boolean tryLock(long timeout, TimeUnit unit)throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}

该方法需要处理中断异常,和lock()方法不一样。

我们继续深入。

public final boolean tryAcquireNanos(int arg, long nanosTimeout)throws InterruptedException {if (Thread.interrupted())throw new InterruptedException();return tryAcquire(arg) ||doAcquireNanos(arg, nanosTimeout);
}

可以看到,它直接通过线程的中断标志位决定是否抛出异常。

之后进行tryAcquire(),这个方法细节上面分析过,它有公平和非公平两种实现,简而言之就是非公平直接尝试CAS加锁,公平则是进入队列排队。

也就是说,最后它会正常加锁,只有失败时才会执行doAcquireNanos()。所以有参的tryLock()方法park线程的细节就在其中。

那下面就看看这个方法的内部。

核心就是线程会被封装Node放到队列中,之后查看时间,如果时间比较长,就park线程直到时间结束后再尝试获取锁;如果时间比较短,就在死循环中等到时间结束然后再次获得锁。

因为park的线程主要会因两个动作结束park,即时间到,或者线程发出中断状态,所以最后会查看park是因为什么结束的。如果是中断则抛出异常,否则尝试获取锁。

private boolean doAcquireNanos(int arg, long nanosTimeout)throws InterruptedException {// 如果等待时间是0秒,直接告辞,拿锁失败  if (nanosTimeout <= 0L)return false;// 设置结束时间。final long deadline = System.nanoTime() + nanosTimeout;// 先扔到AQS队列final Node node = addWaiter(Node.EXCLUSIVE);// 拿锁失败,默认trueboolean failed = true;try {for (;;) {// 如果在AQS中,当前node是head的next,直接抢锁final Node p = node.predecessor();if (p == head && tryAcquire(arg)) {setHead(node);p.next = null; // help GCfailed = false;return true;}// 结算剩余的可用时间nanosTimeout = deadline - System.nanoTime();// 判断是否是否用尽的位置if (nanosTimeout <= 0L)return false;// shouldParkAfterFailedAcquire:根据上一个节点来确定现在是否可以挂起线程if (shouldParkAfterFailedAcquire(p, node) &&// 避免剩余时间太少,如果剩余时间少就不用挂起线程nanosTimeout > spinForTimeoutThreshold)// 如果剩余时间足够,将线程挂起剩余时间LockSupport.parkNanos(this, nanosTimeout);// 如果线程醒了,查看是中断唤醒的,还是时间到了唤醒的。if (Thread.interrupted())// 是中断唤醒的!throw new InterruptedException();}} finally {if (failed)cancelAcquire(node);}
}

2.1.5、总结

ReentrantLock的加锁有公平锁和非公平锁两种方式。

对于非公平锁,任务一开始会直接尝试通过CAS获取锁,失败后才会进入任务队列。并且进入的时候会再次尝试获取锁。整个过程并不考虑其他节点等了多久,所以才是非公平锁。

对于公平锁,任务会按序先进入任务队列,直到有人唤醒他们才会开始获取锁。


http://www.dtcms.com/wzjs/160592.html

相关文章:

  • 网站备案有什么坏处广点通广告平台
  • 建设网站应该加什么服务聚合搜索引擎入口
  • wordpress 下载主题慢西安seo关键词排名
  • 软件测试培训出来能找到工作吗宁波网站seo诊断工具
  • 中文命名网页制作素材会怎么样安徽seo推广公司
  • 用阿里云做网站最新足球赛事
  • 广州网站设计培训刷网站软件
  • 长沙做网站最专业日本搜索引擎naver入口
  • 动态网站开发架构网站站长
  • 有空间与域名 怎么做网站网站设计规划
  • 响应式网站 像素视频剪辑培训班
  • 有了网站后台后怎么做seo优化纯注册app拉新挣钱
  • 推荐做任务网站seo综合查询平台官网
  • 网站开发过程前端后端站长之家是干什么的
  • 做韩国外贸网站建设营销网站
  • 昆明网站建设电话网站域名解析
  • 大连建设学校招生简章站长之家seo查询
  • 静海做网站公司个人网站搭建
  • 珠海企业网站建设报价全球网络营销公司排行榜
  • 代理ip提取网站源码怎么样把广告做在百度上
  • 什么是网站交互aso榜单优化
  • 有没有做兼职的网站做销售记住这十句口诀
  • 长治做网站什么是电商
  • 国外做兼职网站有哪些智能建站abc
  • 电商平台设计电商网站建设最新军事新闻最新消息
  • 知识付费网站源码下载东莞今天新增加的情况
  • 平台电商网站开发国际新闻界期刊
  • php 可以自己做网站吗广州推广引流公司
  • 东莞网站设计哪家强舆情报告范文
  • 做淘宝网站需要什么河南关键词排名顾问