首页 新闻 会员 周边

我想问大家一个问题就是.net中多个线程修改一个对象的引用用加锁么(即lock)?

0
悬赏园豆:20 [已解决问题] 解决于 2010-11-26 21:12

我想问大家一个问题就是.net中多个线程修改一个对象的引用用加锁么(即lock)?

最近遇到了多线程的问题,之后通过加锁(Lock)解决了,但是我一想,如果修改对象引用这个操作在多线程下安全(即不是不线程安全)。那岂不是程序那里都要加锁了,所以我想应该修改引用操作本身就是线程安全的(至少我的程序从来没有因为修改同一个对象的引用出现线程不安全),但是又没有找到权威的证明(即在MSDN中没有找到同一个对象修改引用时线程安全这句话……),所以想大家请教。希望给出答案的出处 ^_^

artcodes的主页 artcodes | 初学一级 | 园豆:180
提问于:2010-11-20 21:05
< >
分享
最佳答案
0

object obj =new object(1);

obj 称为object类型的变量,该变量保持一个对对象 object(1) 的引用。

"修改一个对象的引用"是什么意思?

收获园豆:10
Launcher | 高人七级 |园豆:45045 | 2010-11-21 09:15
之后再来一行obj= new object() 这不就是修改了obj的引用了么 我的意思就是修改引用写个操作是否是线程安全的
artcodes | 园豆:180 (初学一级) | 2010-11-21 09:42
@artcodes:你那不叫修改“对象的引用”,而是修改“变量引用的对象”。这样来理解,你的问题就很好回答了,修改“变量引用的对象”的实质就是修改“变量的值”。在这里,变量 obj 的值即为对象object(1)的引用(可以理解为一个32位的整型数值),而赋值操作(= 运算符)在这里始终是原子操作,也就是说即便是有多个线程同时执行 = 操作,它们依然会按照顺序的形式逐个执行。而你提到的“线程安全”是指在给变量 obj 赋值前,你期望 obj 满足一定的条件(比如为 null),或者 obj 只被赋值一次,那么这时候,你才需要lock来同步你的赋值操作。根据你的需求,如果只是保证 obj 等于null或者等于一个特定的 object 对象,那么使用Interlocked.CompareExchange优于lock原语;如果你要保证 obj只被赋值一次,那么使用double-check才能满足。
Launcher | 园豆:45045 (高人七级) | 2010-11-21 10:25
那我觉得按照你的意思就是C# 中的修改“变量引用的对象”实际上不是线程安全的,存在多个线程同时修改同一个对象实例引用时候出现线程不安全现象,所以MS提供了Interlocked.CompareExchange进行做引用赋值的线程安全保证 对么?
artcodes | 园豆:180 (初学一级) | 2010-11-21 14:43
@artcodes:没有因果关系,只是可以用Interlocked.CompareExchange实现对一个变量实现CAS操作,而不用使用lock等更消耗资源的原语。
Launcher | 园豆:45045 (高人七级) | 2010-11-21 20:01
@Galactica:另外,对变量赋值本身是线程安全,因为“赋值”也是一个原语,和CAS是等效的。所谓“线程安全”是你希望多个原语在一次不被打断的指令流下执行。早期的操作系统是不支持CAS的,因为“比较”,“交换”是两个原语,当并发执行时,不能保证“比较”之后就一定执行“交换”,它可能紧跟另一个“比较”指令。
Launcher | 园豆:45045 (高人七级) | 2010-11-21 20:19
@Galactica:CAS是实现无锁(lock free)数据结构的关键,.net 4.0中的并行集合大量的使用了这种新的数据结构来提高集合的并发性能。
Launcher | 园豆:45045 (高人七级) | 2010-11-21 20:22
找到答案了,引用付值是原子操作 ECMA334 133页
artcodes | 园豆:180 (初学一级) | 2010-11-22 17:00
其他回答(1)
0

程序里很多地方.NET Framework已经很多线程安全方面的工作,但在一些并发性比较大的修改数据问题上最好自己来写

我也是初学者,这仅仅是我的理解哈

收获园豆:10
artwl | 园豆:16736 (专家六级) | 2010-11-20 21:51
谢谢回答,但是我需要的是确定的论据…… 不然我心里不踏实……
支持(0) 反对(0) artcodes | 园豆:180 (初学一级) | 2010-11-20 21:53
查了下资料,也仔细想了一下,多个线程修改一个对像的引用不一定要加锁,线程同步有很多方法,也可以通过其他方法解决。另外,lock本来就是只对引用类型的,锁定的是一个地址 参考:http://www.cnblogs.com/xuqifa100/archive/2010/05/06/1682450.html http://www.cnblogs.com/flying_bat/archive/2007/05/31/765864.html
支持(0) 反对(0) artwl | 园豆:16736 (专家六级) | 2010-11-20 22:14
谢谢回答,但是感觉SynchronizationAttribute 也不太像,因为如果object上标记了SynchronizationAttribute 那岂不是.net根本就没有多线程了……还有我也没有在MSDN中找到object上应用过SynchronizationAttribute 属性的说明
支持(0) 反对(0) artcodes | 园豆:180 (初学一级) | 2010-11-20 23:04
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册