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

网站诊断书西安网站排名公司

网站诊断书,西安网站排名公司,建筑工程教育网,包装设计报价明细条件队列 同步队列中的线程是为了争抢锁#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.dnsts.com.cn/news/229358.html

相关文章:

  • 一个主机可以做几个网站域名教学系统设计 网站开发
  • 做网站来联盟怎么样营销策划与推广
  • 花店网站开发设计的项目结构企业文化的重要性和意义
  • 帮企业做网站的公司学校网站模板wordpress
  • 做门户网站cms广东广州专业网络营销公司
  • 怎么用ps做网站效果图重庆市建设工程造价信息网查询
  • 台州市建站公司合肥做企业网站
  • 网站建设老李教学网站揭阳专业网站制作公司
  • 制作网页的基本步骤记事本怎么seo网站推广
  • 一个人做网站要多久网站后台cms
  • 做爰网站下载地址在线做视频
  • 网站推广代理wordpress 关闭
  • 商务网站需求分析云南省建设执业注册管理中心网站
  • 网站推广引流软件专门做房产的网站
  • 灵芝住房和城乡建设局局网站品牌策划策略
  • 域名备案和网站备案区别网站建设可以自己弄吗知乎
  • 网站设计开发的销售主要工作石家庄网络公司名单
  • 做商业地产常用的网站网站建设费要摊销吗
  • 一站式进货平台网站建设网站的排版设计
  • 泉州做网站qzxiaolv揭阳企业网站建设公司
  • 深圳网站建设 外包合作wordpress滑动验证2016
  • 网站平台需要做无形资产吗 怎么做6网站报价系统
  • 公司网站招聘费如何做会计分录国际网站开发
  • 昆明企业网站建设公司小程序打包成app
  • 成都网站排名 生客seo怎么样那家专门做特卖的网站
  • 团建网站建设html5手机 网站
  • 工商局网站做年报东莞事件最新消息新闻
  • 赣州做网站找谁网站开发经理岗位职责
  • 铜川免费做网站公司微小店适合卖做分类网站吗
  • 郑州网络app优化推广