




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
AbstractQueuedSynchronizer 详解(二) CountDownLatch 源码分析 CountDownLatch 的使用 CountDownLatch 是一个工具类,用于使一个或多个线程等待另一系列线程完成操作,也就 是说一些线程在另外一些完成之后才能继续执行,类似线性。 初始 CountDownLatch 时需要提供一个 count 参数,await 方法将会使线程阻塞,直到这个 值变为 0,countDown()方法可以使 count 值减 1,一旦到达 0 后,调用 await 阻塞的线程将 会得到释放。 CountDown 一般有两个用法。 一个线程等待多个线程 一个线程等待多个线程完成后再执行,比如一个不限时的考试,10 个学生考试,交卷时间 不同,当 10 个学生都交卷后,老师才认为考试结束。下面是该例子: public class ExamDemo public static class Student implements Runnable private int num;/学号 private CountDownLatch countDownLatch; public Student(int num, CountDownLatch countDownLatch) this.num = um; this.countDownLatch = countDownLatch; Override public void run() Random random = new Random(); try TimeUnit.SECONDS.sleep(random.nextInt(10) + 1); catch (InterruptedException e) e.printStackTrace(); System.out.println(“学生“ + num + “交卷了“); /完成工作,将 count-1 countDownLatch.countDown(); public static class Teacher implements Runnable private CountDownLatch countDownLatch; public Teacher(CountDownLatch countDownLatch) this.countDownLatch = countDownLatch; Override public void run() System.out.println(“考试开始,不限时间!“); try /等待 count 变为 0 countDownLatch.await(); catch (InterruptedException e) e.printStackTrace(); System.out.println(“考试结束“); public static void main(String args) Executor executor = Executors.newCachedThreadPool(); CountDownLatch countDownLatch = new CountDownLatch(10); executor.execute(new Teacher(countDownLatch); for (int i = 1; i = 0) setHeadAndPropagate(node, r); p.next = null; / help GC failed = false; return; /检查是否需要将当前线程挂起 if (shouldParkAfterFailedAcquire(p, node) finally if (failed) cancelAcquire(node); 队列的结构如下: 其中 Head 是个空节点,所以一旦前驱节点是头节点,并且要是 count 变为了 0,那么就调 用 setHeadAndPropagate 方法,然后释放头节点。 setHeadAndPropagate 方法主要完成两件 事,第一更改头节点,第二由于此时等待线程可以执行了,将该事件传播给后面的节点, 实现如下: private void setHeadAndPropagate(Node node, int propagate) Node h = head; / Record old head for check below /更改头节点 setHead(node); /* * Try to signal next queued node if: * Propagation was indicated by caller, * or was recorded (as h.waitStatus either before * or after setHead) by a previous operation * (note: this uses sign-check of waitStatus because * PROPAGATE status may transition to SIGNAL.) * and * The next node is waiting in shared mode, * or we dont know, because it appears null * * The conservatism in both of these checks may cause * unnecessary wake-ups, but only when there are multiple * racing acquires/releases, so most need signals now or soon * anyway. */ /如果需要传播 if (propagate 0 | h = null | h.waitStatus 0 | (h = head) = null | h.waitStatus 0) Node s = de.next; if (s = null | s.isShared() doReleaseShared(); 可以看到如果需要传播的话,将会调用 doReleasShared 方法 ,方法如下: private void doReleaseShared() for (;) Node h = head; if (h != null if (ws = Node.SIGNAL) if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0) /重置状态,成功 后,将后继节点唤醒 continue; / loop to recheck cases unparkSuccessor(h); else if (ws = 0 / loop on failed CAS if (h = head) / loop if head changed break; 至此,await 方法就使线程挂起了,下面再分析 countDown 方法。 countDown 方法 countDown 方法用于将 count 值减 1,如果 count 变为 0 则释放所有等待线程,方法的实现如 下: public void countDown() sync.releaseShared(1); releaseShared 方法如下 : public final boolean releaseShared(int arg) /尝试释放共享资源,如果需要释放节点,则释放节点 if (tryReleaseShared(arg) doReleaseShared(); return true; return false; tryReleaseShared 需要在子类中实现,Sync 中的实现如下: protected boolean tryReleaseShared(int releases) / Decrement count; signal when transition to zero for (;) int c = getState(); if (c = 0) return false; int nextc = c-1; if (compareAndSetState(c, nextc) return nextc = 0; 一开始设置了 count,每次 countDown 会使 AQS 的 state-1,一旦变成 0,则返回 true。而 如果变成了 0 后,又调用 countDown 则无效。doReleaseShared 方法用于释
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 农发行衡水市景县2025秋招笔试EPI能力测试题专练及答案
- 农发行宁德市福鼎市2025秋招信息科技岗笔试题及答案
- 农发行郴州市汝城县2025秋招群面案例总结模板
- 农发行成都市温江区2025秋招笔试英语题专练及答案
- 2025年黑河逊克县乡村医生公开招聘19人模拟试卷及1套参考答案详解
- 医院门诊护士个人工作总结11篇
- 中国广电威海市2025秋招技术岗专业追问清单及参考回答
- 2025年威海市立医院公开招聘高层次急需紧缺专业技术人才(33人)考前自测高频考点模拟试题附答案详解(完整版)
- 医生年度履职工作总结(10篇)
- 玉林市中储粮2025秋招综合管理岗高频笔试题库含答案
- 女生穿搭技巧学习通超星期末考试答案章节答案2024年
- 2024年大学试题(政治学)-比较政治制度考试近5年真题集锦(频考类试题)带答案
- 建筑物拆除场地清理垃圾外运施工方案
- 国家开放大学《Web开发基础》形考任务实验1-5参考答案
- 输变电工程施工质量验收统一表式附件1:线路工程填写示例
- 断亲协议书模板
- 给排水设备监控系统
- 中秋国庆假期安全教育
- GB/T 19808-2005塑料管材和管件公称外径大于或等于90mm的聚乙烯电熔组件的拉伸剥离试验
- 北京市幼儿园办园质量督导评估办法(试行)
- 防盗抢演练记录(加油站)
评论
0/150
提交评论