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

网站诊断书北京软件设计公司

网站诊断书,北京软件设计公司,个人养老保险金,wordpress最新文章加图标条件队列 同步队列中的线程是为了争抢锁#xff0c;而条件队列中的线程是主动释放锁#xff0c;挂起自己#xff0c;等条件满足时被别的线程唤醒#xff0c;继续工作。 AQS里只有1个同步队列#xff0c;但可以有多个等待队列#xff0c;每个等待队列对应一个ConditionO…条件队列 同步队列中的线程是为了争抢锁而条件队列中的线程是主动释放锁挂起自己等条件满足时被别的线程唤醒继续工作。 AQS里只有1个同步队列但可以有多个等待队列每个等待队列对应一个ConditionObject对象。 public static void main(String[] args) {ReentrantLock lock new ReentrantLock();Condition con1 lock.newCondition();Condition con2 lock.newCondition(); } // ReentrantLock.java final ConditionObject newCondition() {return new ConditionObject(); }同步队列的头尾节点是head和tail等待队列的头尾节点是firstWaiter和lastWaiter。 同步队列的头结点是哑节点等待队列没有哑结点。 线程想进入同步队列是没有条件的线程想进入等待队列得先获取锁而且还得是独占锁。 同步队列的节点和等待队列的节点都是Node对象线程离开等待队列后会进入同步队列继续获取锁。 等待 释放锁 await() public final void await() throws InterruptedException {if (Thread.interrupted()) // 如果当前线程被设置了中断位则1. 清除中断位2. 抛出异常交给用户处理throw new InterruptedException();ConditionNode node new ConditionNode(); // ConditionNode继承自Node类int savedState enableWait(node); // 当前线程释放锁并且组装node对象LockSupport.setCurrentBlocker(this); // for back-compatibility 向后兼容 与LockSupport.park()组合使用让当前线程抛弃锁boolean interrupted false, cancelled false, rejected false;while (!canReacquire(node)) { // canReacquire表示当前节点是否离开等待对了到了同步队列。如果是则跳出循环if (interrupted | Thread.interrupted()) { // 响应中断if (cancelled (node.getAndUnsetStatus(COND) COND) ! 0) // 详见下文单独介绍这个语句含义是如果被设置中断并且当前节点仍然在等待队列那么离开等待队列响应中断break; // else interrupted after signal} else if ((node.status COND) ! 0) { // 当前节点的status仍包含COND即仍处于等待// 这个方法体目的是阻塞当前线程如果能交给线程池提高并发更好如果不能交给线程池则自己执行LockSupport.park()自己挂起try {if (rejected)node.block();elseForkJoinPool.managedBlock(node);} catch (RejectedExecutionException ex) {rejected true;} catch (InterruptedException ie) {interrupted true;}} else // 代表上一个条件为false即当前节点的status不包含COND即已经离开等待队列。但是canReacquire(node)false表示当前节点还未进入同步队列。因此放弃时间片等别的线程先执行。Thread.onSpinWait(); // awoke while enqueuing}// 运行到此当前线程被唤醒并且在同步队列里LockSupport.setCurrentBlocker(null);node.clearStatus(); // 原子性 node.status 0acquire(node, savedState, false, false, false, 0L); // 尝试获取锁// 运行到此当前线程已经重新获取资源if (interrupted) { // 响应中断if (cancelled) { // 当前节点从等待队列被取消没有进入同步队列unlinkCancelledWaiters(node); // 清理当前节点和被设置为CANCALLED的节点throw new InterruptedException();}Thread.currentThread().interrupt();}}private int enableWait(ConditionNode node) {if (isHeldExclusively()) { // 判断当前线程是否是持锁线程node.waiter Thread.currentThread();node.setStatusRelaxed(COND | WAITING); // COND 2,WAITING 1, 因此node的status3ConditionNode last lastWaiter; // 开始将当前node对象放入条件队列if (last null)firstWaiter node;elselast.nextWaiter node;lastWaiter node; // 结束将当前node对象放入条件队列int savedState getState(); // 获取当前线程的stateif (release(savedState)) // 释放锁并且唤醒同步队列的下一个节点return savedState;}// 如果运行到此说明1. 锁空闲无持锁线程 或者2. 当前线程不是持锁线程因此取消当前节点并且抛出异常node.status CANCELLED; // lock not held or inconsistentthrow new IllegalMonitorStateException(); }node.getAndUnsetStatus(COND) COND) ! 0 这个语句的目的是线程安全地将等待节点移出等待队列即避免多个线程重复将同一个节点移出等待队列。线程如何知道节点在不在等待队列通过status。如果status包含COND表示还在等待队列否则不在。 node.getAndUnsetstatus(COND)是node.status node.status ~COND含义是解除COND位。原理是COND2,用二进制表示是0010(从右往左第二位是1)与非运算之后去掉status第二位的1。 (node.getAndUnsetStatus(COND) COND) ! 0true表示当前节点仍然在等待队列。node.getAndUnsetstatus(COND)解除COND位之后返回的是初始status。node.getAndUnsetStatus(COND) COND是初始状态与COND进行与运算如果初始状态含COND那么结果不等于0含义是当前线程运行时当前节点仍然在等待队列。否则当前节点不在等待队列。 为什么不直接判断COND位而是原子性操作呢是为了线程安全。对于某个等待节点多线程环境下只有第一个线程运行(node.getAndUnsetStatus(COND) COND) ! 0为true只有它的getAndUnsetStatus(COND) 返回值包含COND位。之后的线程的getAndUnsetStatus(COND) 返回值都不包含COND位(node.getAndUnsetStatus(COND) COND) ! 0结果永远是false代表当前节点已经不在等待队列。 唤醒 signal与signalAl public final void signal() {ConditionNode first firstWaiter;if (!isHeldExclusively())throw new IllegalMonitorStateException();if (first ! null)doSignal(first, false); }public final void signalAll() {ConditionNode first firstWaiter;if (!isHeldExclusively())throw new IllegalMonitorStateException();if (first ! null)doSignal(first, true); }private void doSignal(ConditionNode first, boolean all) {while (first ! null) {ConditionNode next first.nextWaiter;if ((firstWaiter next) null)lastWaiter null;if ((first.getAndUnsetStatus(COND) COND) ! 0) {enqueue(first);if (!all)break;}first next;} }signal()方法和signalAll()方法类似都执行参数校验并且交给doSignal()方法执行。 doSignal()方法将节点从等待队列移除放入同步队列。并没有主动唤醒节点线程。 (first.getAndUnsetStatus(COND) COND) ! 0true则当前线程是第一个去除first节点状态COND的线程。因此可以执行enqueue()方法将节点放入同步队列。 如果(first.getAndUnsetStatus(COND) COND) ! 0false则代表当前线程从ConditionNode first firstWaiter语句到本条语句期间first节点的状态已经被别的线程更改了 跳过当前节点尝试更改下一个节点。 signalAll()方法将alltrue代表所有等待节点都会被放入同步队列。
http://www.hkea.cn/news/14313879/

相关文章:

  • php 网站下载器北滘高明网站建设
  • 数字网站建设化妆品购物网站模板下载
  • 网站免费软件下载关于设计的网站
  • 西宁网站公司德州手机网站建设
  • 国内外网站开发技术中国字体设计网
  • 公关策划公司网站源码专门做民宿的网站有哪些
  • 网站建设案例教程全网整合营销外包
  • 做的电影网站很卡营销策划师资格证
  • 下载宝硬盘做网站集团定制网站建设公司
  • 怀集建设房管部门网站网上购物的网站有哪些
  • 有好点的网站建设公司吗番禺人才网官网单位招考
  • 网站推广推广网络培训平台有哪些
  • 网站改版建议策划书和网站合作有哪些活动可以做
  • 关于网站策划书描述准确的有百度网站联盟
  • 在网站开发中如何设置用户登录销售网站开发意义
  • 电子政务 和网站建设总结wordpress 上传apk
  • 江门市住房城乡建设局网站东莞智通人才网最新招聘信息
  • 苏州做企业网站有哪些相册制作软件
  • 仪征做网站公司网站开发项目计划书模板
  • 品牌网站建设 蝌蚪小7网站开发费用清单
  • 自做网站的步骤小程序快速搭建
  • wordpress 网站播放器插件网站seo 最好
  • html好看的网站的代码百度推广的方式
  • 域名被锁定网站打不开合肥房产网官网
  • 网站开发最新书籍桂林象鼻山离哪个高铁站近
  • 建站的费用网络热词
  • 集团网站群图虫网官网入口
  • 网站建设需要步骤随机关键词生成器
  • 做展示网站网站建设与管理学习什么
  • 北京经济技术开发区建设局网站定制衣服