




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、JAVA并发编程实践中提供了 3中非阻塞算法的示例。第一个示例,非阻塞计数器。CAS比较并交换即Compare-And-Swap。假设CAS有3个操作数-内存位置V、旧的预测值A和新值B,那么它的典型模式为:首先从 V中读取值A,由A生成新值B,然后使用CAS 原子化地把V的值改成B,并且期间不能有其他线程改变V的值,因为CAS能够发现来自其他线程的干扰。view plaincopy to clipboardprint?01.代码1使用CAS实现的非阻塞计数器02.ThreadSafe03.public class CasCounter 04.private SimulatedCAS valu
2、e;05.publicintgetValue() 06.return value.get(); TOC o 1-5 h z 07.08. v;do v = value.get(); 1while(v !=pareAndSwap(v, v + 1);2return v +1;代码2模才C CAS操作ThreadSafepublic class SimulatedCAS GuardedBy(this) private int value;public synchronized int get() return value; public synch
3、ronized int compareAndSwap(int expectedValue,int newValue) int oldValue = value;if (oldValue = expectedValue)value = newValue;return oldValue;public synchronized boolean compareAndSet(int expectedValue,int newValue) return (expectedValue= compareAndSwap(expectedValue, newValue);代码1使用CAS实现的非阻塞计数器Thre
4、adSafe public class CasCounter private SimulatedCAS value; public int getValue() return value.get(); public int increment() int v; do v = value.get(); 1 while (v != pareAndSwap(v, v + 1);2return v + 1; 代码2模CAS操作 ThreadSafe public class SimulatedCAS GuardedBy(this) private int value;public synchroniz
5、ed int get() return value; public synchronized int compareAndSwap(int expectedValue, int newValue) int oldValue = value;if (oldValue = expectedValue) value = newValue;return oldValue; public synchronized boolean compareAndSet(int expectedValue, int newValue) return (expectedValue= compareAndSwap(exp
6、ectedValue, newValue); 假设有两个线程,同时执行到 1 ,获得了 value的旧值;然后同时执行到2 ,根据原则当多个线程试图使用CAS同时更新相同的变量时,其中一个会胜出,并更新变量的值,而其他线程都会失败,重新尝试。”可知,其中一个线程完成了加1操作,而另一个线程失败,重新do循环。让我们细细体会一下这个原则是怎么得到的:一个线程完成了加1操作后,另一个线程使用 CAS时,旧的预期值没有变但内存位置V的值已经更新了,所以此时V的值不等于旧的预期值而导致失败! 第二个示例,非阻塞栈view plaincopy to clipboardprint?01.代码3使用Trei
7、ber算法的非阻塞栈02.ThreadSafe03.public class ConcurrentStack 04.05.06.07.08.09.代码3AtomicReferenceNode top = new AtomicReferenceNode(); public void push(E item) Node newHead = new Node(item);Node oldHead;do oldHead = top.get();newHead.next = oldHead; 1 while (!pareAndSet(oldHead, newHead); 2public E pop()
8、Node oldHead;Node newHead;do oldHead = top.get();if (oldHead = null)return null;newHead = oldHead.next; while (!pareAndSet(oldHead, newHead);return oldHead.item;private static class Node public final E item;public Node next;public Node(E item) this.item = item;使用Treiber算法的非阻塞栈ThreadSafepublic class
9、ConcurrentStack AtomicReferenceNode top = new AtomicReferenceNode(); public void push(E item) Node newHead = new Node(item);Node oldHead;do oldHead = top.get();newHead.next = oldHead;1 while (!pareAndSet(oldHead, newHead); 2 public E pop() Node oldHead;Node newHead;do oldHead = top.get(); if (oldHea
10、d = null) return null; newHead = oldHead.next; while (!pareAndSet(oldHead, newHead); return oldHead.item;private static class Node public final E item;public Node next; public Node(E item) this.item = item; 注: AtomicReferencecompareAndSet ( V expect, V update)若当前值与期望值 expect相等时,原子化地将update值赋给当前值。假设有
11、两个线程,同时执行到1,获得了栈顶元素,并创建了一个新节点指向当前栈顶; 然后同时执行到2 ,根据原则”当多个线程试图使用CAS同时更新相同的变量时,其中一个会胜出,并更新变量的值,而其他线程都会失败,重新尝试。”可知,其中一个线程完成了插入操作,而另一个线程失败,重新 do循环。让我们细细体会一下这个原则是怎么得 到的:一个线程完成了插入操作后,另一个线程使用CAS时,旧的预期值没有变但当前栈顶的值已经更新了,所以此时栈顶的值不等于旧的预期值而导致失败! 第三个示例,非阻塞链表view plaincopy to clipboardprint?01.代码4 Michael-Scott非阻塞队列
12、算法中的插入02.ThreadSafe03.public class LinkedQueue 04. private static class Node 05.final E item;06.final AtomicReferenceNode next;07.public Node(E item, Node next) 08.this.item = item;09.this.next = new AtomicReferenceNode(next);private final Node dummy = new Node(null, null);private final AtomicRefere
13、nceNode head= new AtomicReferenceNode(dummy);private final AtomicReferenceNode tail= new AtomicReferenceNode(dummy);public boolean put(E item) Node newNode = new Node(item, null);while (true) Node curTail = tail.get();Node tailNext = curTail.next.get();if (curTail = tail.get() ?if (tailNext != null)
14、 A/ Queue in intermediate state, advance tailpareAndSet(curTail, tailNext); B else /In quiescent state, try inserting new nodeif (curTpareAndSet(null, newNode) C/ Insertion succeeded, try advancing tail TOC o 1-5 h z pareAndSet(curTail, newNode);Dreturn true;代码4 Michael-Scott非阻塞队列算法中的插入ThreadSafepub
15、lic class LinkedQueue private static class Node final E item;final AtomicReferenceNode next;public Node(E item, Node next) this.item = item;this.next = new AtomicReferenceNode(next);private final Node dummy = new Node(null, null);private final AtomicReferenceNode head=new AtomicReferenceNode(dummy);
16、private final AtomicReferenceNode tail=new AtomicReferenceNode(dummy);public boolean put(E item) Node newNode = new Node(item, null);while (true) Node curTail = tail.get();Node tailNext = curTail.next.get();if (curTail = tail.get() ?if (tailNext != null) A/ Queue in intermediate state, advance tail
17、pareAndSet(curTail, tailNext); B else / In quiescent state, try inserting new nodeif (curTpareAndSet(null, newNode) C/ Insertion succeeded, try advancing tail pareAndSet(curTail, newNode); D return true;首先看?处,为什么要判断 curTail = tail.get()呢?必须要有这个判断来保证数据结构总能处于一致状态。如果没有这个判断的话可能出现下面状况。细细思索一下,如果没有 curTail
18、 = tail.get()这个的话,一个线程将元素3加入队列,而另一个线程却把next指针的指向了 3,元素3就这样被丢弃了,这当然是不行的!也就是我们 下文所说的第一个诀窍。插入新的元素涉及到两个指针的更新(两个指针分别为队尾指针和队尾元素的next指针),需要两个操作过程。第一,更新当前队尾元素的 next指针,将新元素插入到列表队尾;第 二,释放队尾指针,指向新的最末元素。在这两个操作之间,队列处于中间状态,看图示。图a插入前稳定状态图b插入期间,队列处于中间状态图c插入完成后,队列再一次回到稳定状态有几个诀窍来完成我们的链表。第一个诀窍是即使在多步更新中,也要确保数据结构总能处 于一致状态。也就是说,如果线程B到达时发现线程 A正在更新中,B能够知晓操作已经部 分完成并且知道不能立即开始自己的更新。那么B就开始等待(通过反复检查队列状态)直到A完成更
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 河南省职业学校数学试卷
- 河南禹州中招数学试卷
- 济南初三一模数学试卷
- 健康管理师课件下载
- 2025年中国刮泥机行业市场发展现状及投资规划建议报告
- 中国木材保护工业行业市场发展监测及投资潜力预测报告
- 1,4二氧六环项目可行性研究报告
- 健康知识课件下载
- 2021-2026年中国面粉加工市场调查研究及行业投资潜力预测报告
- 奇瑞汽车战略发展研究报告
- 南昌市2025届高三摸底测试(零模)数学试卷(含答案)
- GB/T 44099-2024学生基本运动能力测评规范
- 流媒体服务的兴起与电影产业的转型
- 幼儿园美术案例分析与措施
- 高斯小学奥数二年级(上)第05讲 图形规律进阶
- MOOC 化工过程与控制仿真实习-北京化工大学 中国大学慕课答案
- 《保温保冷技术》
- 新版人教版七年级全册英语单词表(含音标)可打印
- 2024-2026胡润财富报告
- 呼叫中心投标技术方案样本
- 人教版六年级数学下册全册分层作业设计含答案
评论
0/150
提交评论