- 浏览: 518736 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (161)
- 多线程与并发编程 (20)
- 算法和数据结构 (8)
- 缓存 (0)
- HttpClient (2)
- 疑难杂症 (11)
- Java内存管理 (17)
- 分布式开发 (14)
- Linux常用命令 (10)
- OSGI (0)
- UML (2)
- 趣味面试题 (5)
- 设计模式 (8)
- Java类加载 (2)
- JSTL (1)
- Web 服务器 (4)
- IT人生 (3)
- Java基础 (11)
- Flash技术 (7)
- 新知识 (3)
- 常用速备速查 (4)
- 版本控制 (1)
- Java集合工具类 (6)
- web前端技术 (1)
- 趣味话题 (1)
- 安全 (0)
- 架构设计 (5)
- Spring (4)
- 负载均衡技术 (2)
- 持久层技术 (2)
- MySQL单机多实例方案 (1)
- 收藏备用 (0)
- 性能优化 (3)
最新评论
-
liuwuhen:
...
Pushlet的工作原理 -
fbwfbi:
fengchuizhuming 写道楼主的完全正确。鉴定完毕楼 ...
硬件同步原语(CAS)理论 -
passerby_whu:
uule 写道这个测试后结果为:“testPageConten ...
FutureTask的使用方法和使用实例 -
fengchuizhuming:
楼主的完全正确。鉴定完毕
硬件同步原语(CAS)理论 -
edwardjuice:
FutureTask的使用方法和使用实例
在Java并发编程中,常常出现一些因为线程安全问题而需要加锁来保证同步,而在Java5之后,出现了新的并发包,它的出现使得同步效率更加高效,而所有concurrent包的理论基础都是基于硬件同步原语理论,它是基于Cpu硬件的同步,效率比软件中通过锁定(排它锁)效率高。
大多数现代处理器都包含对多处理的支持。当然这种支持包括多处理器可以共享外部设备和主内存,同时它通常还包括对指令系统的增加来支持多处理的特殊要求。特别是,几乎每个现代处理器都有通过可以检测或阻止其他处理器的并发访问的方式来更新共享变量的指令。
支持并发的第一个处理器提供原子的测试并设置操作,通常在单位上运行这项操作。现在的处理器(包括 Intel 和 Sparc 处理器)使用的最通用的方法是实现名为 比较并转换 或 CAS 的原语。(在 Intel 处理器中,比较并交换通过指令的 cmpxchg 系列实现。PowerPC 处理器有一对名为“加载并保留”和“条件存储”的指令,它们实现相同的目地;MIPS 与 PowerPC 处理器相似,除了第一个指令称为“加载链接”。)
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无 论哪种情况,它都会在 CAS 指令之前返回该位置的值。(在 CAS 的一些特殊情况下将仅返回 CAS 是否成功,而不提取当前值。)CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。”
通常将 CAS 用于同步的方式是从地址 V 读取值 A,执行多步计算来获得新值 B,然后使用 CAS 将 V 的值从 A 改为 B。如果 V 处的值尚未同时更改,则 CAS 操作成功。
类似于 CAS 的指令允许算法执行读-修改-写操作,而无需害怕其他线程同时修改变量,因为如果其他线程修改变量,那么 CAS 会检测它(并失败),算法可以对该操作重新计算。清单 3 说明了 CAS 操作的行为(而不是性能特征),但是 CAS 的价值是它可以在硬件中实现,并且是极轻量级的(在大多数处理器中):
public class SimulatedCAS { private int value; public synchronized int getValue() { return value; } public synchronized int compareAndSwap(int expectedValue, int newValue) { if (value == expectedValue) value = newValue; return value; } } |
基于 CAS 的并发算法称为 无锁定 算 法,因为线程不必再等待锁定(有时称为互斥或关键部分,这取决于线程平台的术语)。无论 CAS 操作成功还是失败,在任何一种情况中,它都在可预知的时间内完成。如果 CAS 失败,调用者可以重试 CAS 操作或采取其他适合的操作。清单 4 显示了重新编写的计数器类来使用 CAS 替代锁定:
public class CasCounter { private SimulatedCAS value; public int getValue() { return value.getValue(); } public int increment() { int oldValue = value.getValue(); while (value.compareAndSwap(oldValue, oldValue + 1) != oldValue) oldValue = value.getValue(); return oldValue + 1; } } |
|
|
如果每个线程在其他线程任意延迟(或甚至失败)时都将持续进行操作,就可以说该算法是
无等待
的。与此形成对比的是,
无锁定
算法要求仅
某个
线程总是执行操作。(无等待的另一种定义是保证每个线程在其有限的步骤中正确计算自己的操作,而不管其他线程的操作、计时、交叉或速度。这一限制可以是系统中线程数的函数;例如,如果有 10 个线程,每个线程都执行一次
CasCounter.increment()
操作,最坏的情况下,每个线程将必须重试最多九次,才能完成增加。)
再过去的 15 年里,人们已经对无等待且无锁定算法(也称为 无阻塞算法 ) 进行了大量研究,许多人通用数据结构已经发现了无阻塞算法。无阻塞算法被广泛用于操作系统和 JVM 级别,进行诸如线程和进程调度等任务。虽然它们的实现比较复杂,但相对于基于锁定的备选算法,它们有许多优点:可以避免优先级倒置和死锁等危险,竞争比较 便宜,协调发生在更细的粒度级别,允许更高程度的并行机制等等
评论
楼上完全错误,已证明。 CAS 有两种形式,一种是不管操作成功与否,都是返回原值(旧),另一种就是就是返回True 或 False , 楼主给出的代码描述是错的。标准的如下:
CAS原子操作在维基百科中的代码描述如下:
1: int compare_and_swap(int* reg, int oldval, int newval)
2: {
3: ATOMIC();
4: int old_reg_val = *reg;
5: if (old_reg_val == oldval)
6: *reg = newval;
7: END_ATOMIC();
8: return old_reg_val;
9: }
也就是检查内存*reg里的值是不是oldval,如果是的话,则对其赋值newval。上面的代码总是返回old_reg_value,调用者如果需要知道是否更新成功还需要做进一步判断,为了方便,它可以变种为直接返回是否更新成功,如下:
1: bool compare_and_swap (int *accum, int *dest, int newval)
2: {
3: if ( *accum == *dest ) {
4: *dest = newval;
5: return true;
6: }
7: return false;
8: }
不过这个while (value.compareAndSwap(oldValue, oldValue + 1) != oldValue)确实有问题,当成功的时候,increase会增加2,不是1.
另外,之所以很多实现返回bool,是为了更清楚到底成功没,像你这样的实现并不清楚CAS到底是否成功。
C#的实现是:bool CompareExchange(ref object location, object value,object newValue)。
感觉更好,通过传入ref,即能修改值为最新值,同时bool返回是否设置新值成功。
oldValue = value.getValue();
return oldValue + 1;
这个例子让我很晕,费解.
value.compareAndSwap(oldValue, oldValue + 1) != oldValue,这个不是恒等式么?
发表评论
-
死锁实例
2011-05-19 14:21 1902下面这道题,是考死锁的,比较简单,想两个问题: 1.什么时候 ... -
Java存储模型
2011-05-18 13:29 01.什么是存储模型 没有适当的同步,编译器生成指令的次序,可 ... -
设计模式-组合模式
2011-05-16 15:48 1071组合模式的定义: 将对象组合成树的形式来表示整体和局部之 ... -
CompleteService介绍和使用实例
2011-05-11 17:31 3861当向Executor提交批处理任务时,并且希望在它们完成后获得 ... -
CyclicBarrier的使用实例
2011-05-11 15:45 1438CyclicBarrier允许给定数量的线程全部到达关卡点时, ... -
CopyOnWriteArrayList工作原理和实例
2011-05-05 23:43 3340CopyOnWriteArrayList顾名思义,在写入操作时 ... -
Semaphore的介绍和使用实例
2011-04-27 22:32 2766Semaphore可以用来控制能 ... -
FutureTask的使用方法和使用实例
2011-04-27 15:34 13251FutureTask是一种可以取消的异步的计算任务。它的计算是 ... -
CountDownLatch的使用实例
2011-04-26 22:20 8179CountDownLatch CountDownl ... -
Java 并发编程基础-共享对象
2011-04-19 14:48 1405Java 并发编程基础 ... -
从JVM并发看CPU内存指令重排序(Memory Reordering)
2011-04-18 16:17 1445我们都知道,现在的计算机, cpu 在计算的时候 ... -
Java并发编程基础
2011-04-15 14:55 1511Java 并发编程基 ... -
Java多线程基础
2011-04-13 15:52 4697Java 多线程基础 ... 2 ... -
java5中使用interrupt()来停止java线程的方法(转)
2010-08-18 23:24 3057在开发java多线程时,如果要停止线程这个问题很头痛吧,不过在 ... -
Java 中的Double Check Lock(转)
2010-07-27 21:13 8040对于多线程编程来说,同步问题是我们需要考虑的最多的问题,同步的 ... -
并发访问的问题解决方案
2010-07-26 18:15 1965目前正在做基于Red 5 的Meeting系统,我们会在Mee ... -
用并发包中的重入锁实现生产消费模型
2010-06-15 00:07 1397传统的生产消费模型,实际上是通过一个条件来调节生产者和消费者线 ... -
ThreadLocal原理(转)
2010-03-24 18:06 2125http://jzhua.iteye.com/blog/517 ... -
(转)Java偏向锁实现原理(Biased Locking)
2010-03-21 22:24 1324http://www.iteye.com/topic/5180 ... -
生产消费模型实例
2010-03-02 23:23 1674“生产者-消费者-仓储”模型,包含三种角色: 1.生产者 ...
相关推荐
详细介绍了ARM架构上的硬件同步原语,并介绍了LDREX/STREX指令实现同步操作的原理和具体实现
英文版ARM公司技术资料,讲述ARMv6的同步原语以及如何在ARMv5之前的CPU上通过 SWP 和 SWPB 指令实现同步。
ecos系统同步原语, 包含互斥,信号量, 信箱, 事件, Spinlock ,条件变量。
JVM同步原语 volatile CAS 线程安全 保护“共享数据” 低级并发工具 原子变量 锁(内部锁和显式锁) 线程安全容器 同步容器 并发容器 阻塞队列 高级线程协作工具 信号量 闭锁 关卡 ...
总结了 verilog一些典型的概念和用法
fifolock 一个灵活的低级工具,用于在asyncio Python中创建同步原语
一般说,同步机构是由若干条原语——同步原语——所组成。本实验要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。 三. 实验题目 模拟PV操作同步机构,且用PV操作解决...
1、与全局时钟资源相关的原语常用的与全局时钟资源相关的Xilinx器件原语 2、全局时钟资源的使用方法 3、全局时钟资源的例化方法
cpp11-on-multicore, 在C 11中,多线程应用程序的各种同步原语 C 11中多线程应用程序的各种同步原语。在博客文章中,信号量是令人惊讶的。代码是在许可协议下发布的。 查看 LICENSE 文件。如何构建测试首先,你必须...
如何用PV原语实现进程间的互斥与同步 P操作和V操作是不可中断的程序段,称为原语。PV原语及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量sem是一整数,sem大于等于零时代表可供并发进程使用的资源实体...
高可移植的C系统库:线程和同步原语,套接字(TCP,UDP,SCTP),IPv4和IPv6,IPC,散列函数(MD5,SHA-1,SHA-2,SHA-3,GOST),二进制树 ,AVL)等等。 本地代码性能。
更高级的同步原语。 实现了一些 Go 同步原语。 令牌 提供令牌实现。 只有拥有Token才能做事,然后才能将令牌移交给其他人。 批 提供批量实现。 类似于errgroup ,可以返回每个任务的所有错误结果。 任何 提供部分...
1. 介绍 2. 初始代码 3. 任务 4. 测试
它还公开了用于创建您自己的有效同步原语的低级API。 在x86_64 Linux上进行测试时,发现parking_lot::Mutex速度比std::sync::Mutex速度快1.5倍,而在多线程竞争时,速度最高可快5倍。 RwLock的数字取决于读取器和...
Xilinx原语详解 包括 7series 和 ultrascale系列的 原语库模块调用, 支持 verilog 和 vhdl两种硬件语言的模块代码调用
异步同步原语。 此板条箱提供以下原语: Barrier -使任务可以同时同步所有任务。 Mutex -互斥锁。 RwLock读写器锁,允许任意数量的读取器或单个写入器。 Semaphore -限制并发操作的数量。 执照 根据以下任一...
用于操作系统的编程,运用P,V原语实现进程间同步与互斥
浅析Verilog硬件原语verilog硬件原语浅析_工学_高等教育_教育专区。关于Verilog原语的简单介绍,适合初学者读 浅析Verilog HDL 硬件语义
xilinx V6系列原语程序 包含所有原语 直接复制代码到工程文件即可
自旋 基于自旋的同步原语。 此板条箱在std::sync提供了版本。 由于同步是通过旋转完成的,因此这些原语适合在no_std环境中使用。 在决定使用spin之前,我们建议阅读,其中讨论了spinlock的优缺点。 如果您可以访问...