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

建设一个网站的具体步骤滁州seo网站排名优化

建设一个网站的具体步骤,滁州seo网站排名优化,校园门户网站建设先进,app搭建流程1. Condition的signal方法分析 分为了几个部分#xff1a; ● 确保执行signal方法的是持有锁的线程 ● 脱离Condition的队列 ● 将Node状态从-2改为0 ● 将Node添加到AQS队列 ● 为了避免当前Node无法在AQS队列正常唤醒做了一些判断和操作 // 线程挂起后#xff0c;可以基于…1. Condition的signal方法分析 分为了几个部分 ● 确保执行signal方法的是持有锁的线程 ● 脱离Condition的队列 ● 将Node状态从-2改为0 ● 将Node添加到AQS队列 ● 为了避免当前Node无法在AQS队列正常唤醒做了一些判断和操作 // 线程挂起后可以基于signal唤醒~ public final void signal() {// 在ReentrantLock中如果执行signal的线程没有持有锁资源直接扔异常 if (!isHeldExclusively()) throw new IllegalMonitorStateException(); // 拿到排在Condition首位的Node Node first firstWaiter; // 有Node在排队才需要唤醒如果没有直接告辞~~ if (first ! null) doSignal(first); } // 开始唤醒Condition中的Node中的线程 private void doSignal(Node first) { // 先一波do-while走你~~~ do { // 获取到第二个节点并且将第二个节点设置为firstWaiter if ( (firstWaiter first.nextWaiter) null) // 说明就一个节点在Condition队列中那么直接将firstWaiter和lastWaiter置位null lastWaiter null; // 如果还有nextWaiter节点因为当前节点要被唤醒了脱离整个Condition队列。将nextWaiter置位null first.nextWaiter null; // 如果transferForSignal返回true一切正常退出while循环 } while (!transferForSignal(first) // 如果后续节点还有往后面继续唤醒如果没有退出while循环 (first firstWaiter) ! null); } // 准备开始唤醒在Condition中排队的Node final boolean transferForSignal(Node node) { // 将在Condition队列中的Node的状态从-2改为0代表要扔到AQS队列了。 if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) // 如果失败了说明在signal之前应当是线程被中断了从而被唤醒了。 return false; // 如果正常的将Node的状态从-2改为0这是就要将Condition中的这个Node扔到AQS的队列。 // 将当前Node扔到AQS队列返回的p是当前Node的prev Node p enq(node); // 获取上一个Node的状态 int ws p.waitStatus; // 如果ws 0 说明这个Node已经被取消了。 // 如果ws状态不是取消将prev节点的状态改为-1,。 if (ws 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL)) // 如果prev节点已经取消了可能会导致当前节点永远无法被唤醒。立即唤醒当前节点基于acquireQueued方法 // 让当前节点找到一个正常的prev节点并挂起线程 // 如果prev节点正常但是CAS修改prev节点失败了。证明prev节点因为并发原因导致状态改变。还是为了避免当前 // 节点无法被正常唤醒提前唤醒当前线程基于acquireQueued方法让当前节点找到一个正常的prev节点并挂起线程 LockSupport.unpark(node.thread); // 返回true return true; } 2. Conditiond的await方法分析后置分析 分为了几个部分 ● 唤醒之后要先确认是中断唤醒还是signal唤醒还是signal唤醒后被中断 ● 确保当前线程的Node已经在AQS队列中 ● 执行acquireQueued方法等待锁资源。 ● 在获取锁资源后要确认是否在获取锁资源的阶段被中断过如果被中断过并且不是THROW_IE那就确保 interruptMode是REINTERRUPT。 ● 确认当前Node已经不在Condition队列中了 ● 最终根据interruptMode来决定具体做的事情 ● 0嘛也不做。 ● THROW_IE抛出异常 ● REINTERRUPT执行线程的interrupt方法 // 现在分析await方法的后半部分 public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node addConditionWaiter(); int savedState fullyRelease(node); // 中断模式~ int interruptMode 0; while (!isOnSyncQueue(node)) { LockSupport.park(this); // 如果线程执行到这说明现在被唤醒了。 // 线程可以被signal唤醒。如果是signal唤醒可以确认线程已经在AQS队列中 // 线程可以被interrupt唤醒线程被唤醒后没有在AQS队列中。 // 如果线程先被signal唤醒然后线程中断了。。。。做一些额外处理 // checkInterruptWhileWaiting可以确认当前中如何唤醒的。 // 返回的值有三种 // 0正常signal唤醒没别的事不知道Node是否在AQS队列// THROW_IE-1中断唤醒并且可以确保在AQS队列 // REINTERRUPT1signal唤醒但是线程被中断了并且可以确保在AQS队列 if ((interruptMode checkInterruptWhileWaiting(node)) ! 0) break; } // Node一定在AQS队列 // 执行acquireQueued尝试在ReentrantLock中获取锁资源。 // acquireQueued方法返回true代表线程在AQS队列中挂起时被中断过 if (acquireQueued(node, savedState) interruptMode ! THROW_IE) // 如果线程在AQS队列排队时被中断了并且不是THROW_IE状态确保线程的interruptMode是REINTERRUPT // REINTERRUPTawait不是中断唤醒但是后续被中断过 interruptMode REINTERRUPT; // 如果当前Node还在condition的单向链表中脱离Condition的单向链表 if (node.nextWaiter ! null) unlinkCancelledWaiters(); // 如果interruptMode是0说明线程在signal后以及持有锁的过程中没被中断过什么事都不做 if (interruptMode ! 0) // 如果不是0~ reportInterruptAfterWait(interruptMode); } // 判断当前线程被唤醒的模式确认interruptMode的值。 private int checkInterruptWhileWaiting(Node node) { // 判断线程是否中断了。 return Thread.interrupted() ? // THROW_IE代表线程是被interrupt唤醒的需要向上排除异常 // REINTERRUPT代表线程是signal唤醒的但是在唤醒之后被中断了。(transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) : // 线程是正常的被signal唤醒并且线程没有中断过。 0; } // 判断线程到底是中断唤醒的还是signal唤醒的 final boolean transferAfterCancelledWait(Node node) { // 基于CAS将Node的状态从-2改为0 if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) { // 说明是中断唤醒的线程。因为CAS成功了。 // 将Node添加到AQS队列中~如果是中断唤醒的当前线程同时存在Condition的单向链表以及AQS的队列中 enq(node); // 返回true return true; } // 判断当前的Node是否在AQS队列signal唤醒的但是可能线程还没放到AQS队列 // 等到signal方法将线程的Node扔到AQS队列后再做后续操作 while (!isOnSyncQueue(node)) // 如果没在AQS队列上那就线程让步稍等一会Node放到AQS队列再处理看CPU Thread.yield(); // signal唤醒的返回false return false; } // 确认Node是否在AQS队列上 final boolean isOnSyncQueue(Node node) { // 如果线程状态为-2肯定没在AQS队列// 如果prev节点的值为null肯定没在AQS队列 if (node.waitStatus Node.CONDITION || node.prev null) // 返回false return false; // 如果节点的next不为null。说明已经在AQS队列上。、 if (node.next ! null) // 确定AQS队列上有 return true; // 如果上述判断都没有确认节点在AQS队列上在AQS队列中寻找一波 return findNodeFromTail(node); } // 在AQS队列中找当前节点 private boolean findNodeFromTail(Node node) { // 拿到尾节点 Node t tail; for (;;) { // tail是否是当前节点如果是说明在AQS队列 if (t node) // 可以跳出while循环 return true; // 如果节点为nullAQS队列中没有当前节点 if (t null) // 进入while让步一手 return false; // t向前引用 t t.prev; } } private void reportInterruptAfterWait(int interruptMode) throws InterruptedException { // 如果是中断唤醒的await直接抛出异常 if (interruptMode THROW_IE) throw new InterruptedException(); // 如果是REINTERRUPTsignal后被中断过 else if (interruptMode REINTERRUPT) // 确认线程的中断标记位是true // Thread.currentThread().interrupt(); selfInterrupt(); } 3 Condition的awaitNanossignalAll方法分析 awaitNanos仅仅是在await方法的基础上做了一内内的改变整体的逻辑思想都是一样的。 挂起线程时传入要阻塞的时间时间到了自动唤醒走添加到AQS队列的逻辑 // await指定时间多了个时间到了自动醒。 public final long awaitNanos(long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node addConditionWaiter(); int savedState fullyRelease(node); // deadline当前线程最多挂起到什么时间点final long deadline System.nanoTime() nanosTimeout; int interruptMode 0; while (!isOnSyncQueue(node)) { // nanosTimeout的时间小于等于0直接告辞 if (nanosTimeout 0L) { // 正常扔到AQS队列 transferAfterCancelledWait(node); break; } // nanosTimeout的时间大于1000纳秒时才可以挂起线程 if (nanosTimeout spinForTimeoutThreshold) // 如果大于正常挂起 LockSupport.parkNanos(this, nanosTimeout); if ((interruptMode checkInterruptWhileWaiting(node)) ! 0) break; // 计算剩余的挂起时间可能需要重新的走while循环再次挂起线程 nanosTimeout deadline - System.nanoTime(); } if (acquireQueued(node, savedState) interruptMode ! THROW_IE) interruptMode REINTERRUPT; if (node.nextWaiter ! null) unlinkCancelledWaiters(); if (interruptMode ! 0) reportInterruptAfterWait(interruptMode); // 剩余的挂起时间 return deadline - System.nanoTime(); } signalAll方法。这个方法一看就懂之前signal是唤醒1个这个是全部唤醒 // 以do-while的形式将Condition单向链表中的所有Node全部唤醒并扔到AQS队列 private void doSignalAll(Node first) { // 将头尾都置位null~ lastWaiter firstWaiter null; do { // 拿到next节点的引用 Node next first.nextWaiter; // 断开当前Node的nextWaiter first.nextWaiter null; // 修改Node状态扔AQS队列是否唤醒 transferForSignal(first); // 指向下一个节点 first next; } while (first ! null); }
http://www.yutouwan.com/news/266825/

相关文章:

  • 新素材网站基于php mysql的网站开发
  • 餐饮网站建设的模板房产cms系统
  • 网站排行榜网站建设有几大板块
  • 深圳做小程序网站开发dz论坛做分类网站
  • 如何查看网站的浏览量看男科比较正规的医院
  • 十堰市建设工程管理处网站石家庄有哪些公司可以做网站
  • 网站没流量google网站打不开
  • 嘉兴哪里可以做淘宝网站电脑培训班在哪里有最近的
  • 培训网站推荐直聘最新招聘信息
  • 有没有做企业网站的兰州新区规划建设局网站
  • 网站做交叉连接会网站开发没学历
  • 大学生网站开发总结报告移动网站建设制作
  • 有网站域名及空间 别人帮建网站做外贸经常用的网站
  • 湛江做网站需要什么动漫网站设计模板
  • 怎么做网站xml地图网络营销的网站分类有
  • 网站建设.龙兵科技网站如何在google提交收录
  • 网站转换率自学网站建设工资
  • 网站抠图怎么做的html5开发网站
  • ui设计个人作品集seo代码优化步骤
  • 建设银行网站怎么打印明细网站架设
  • 帮人家做网站能赚多少钱网站设计与网站开发是同时进行的
  • 网站代码管理威海营销型网站建设
  • 网站负责人核验照片广州哪家做网站价格好
  • 浙江怎么制作网站网站备案的要求是什么
  • 做室内效果图网站怎样找到工厂直招网站
  • 网站建设代理都有哪些网站建设的费用计入
  • 世界上最有趣的网站广州seo网站优化培训
  • 网站推广渠道有哪些网站建设 2018
  • 中国百科网vip钓鱼网站开发wordpress去除仪表盘
  • 从seo角度去建设网站服务器租用