Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 对象引用的原子性_.net_Multithreading_Locking - Fatal编程技术网

.net 对象引用的原子性

.net 对象引用的原子性,.net,multithreading,locking,.net,Multithreading,Locking,我刚刚遇到了一个问题——在C#中,是否可以安全地跨线程访问对象 例如,使用代码 //Somewhere long ago MyClass myVar = new MyClass("First Instance"); //Then later, happening at the same time //In thread one myVar = new MyClass("Second Instance"); //In thread two myVar.PrintName(); 我不在乎是否使

我刚刚遇到了一个问题——在C#中,是否可以安全地跨线程访问对象

例如,使用代码

//Somewhere long ago
MyClass myVar = new MyClass("First Instance");

//Then later, happening at the same time
//In thread one
myVar = new MyClass("Second Instance");

//In thread two
myVar.PrintName();
我不在乎是否使用了第一个或第二个实例,但是否有可能myVar在某个点上根本无效(例如,指向一个不存在的位置,因为对象引用在另一个线程中使用之前可能只更新了一部分)


关于锁的附带问题:

如果我留下一个锁,那么所有未完成的写操作都会被提交到内存中吗


我这里的问题是,如果我在锁中引用一个变量,我知道只有一个线程可以同时访问锁-但是我是否会在一个线程中写入变量(并且只对缓存进行写入),然后在另一个线程中甚至在锁内获取变量的旧值(因为缓存未提交,或者我在该线程的缓存中仍然有一个旧值)?

您问题中的代码示例是线程安全的。显然,这取决于您在该构造函数中执行的操作,但“通常”myVar ref将是有效的(通常情况下,您可以执行一些低级操作,如FormatterServices等)。将使用构造函数创建一个新对象,并将自动返回到正确的线程。对我来说,通过在每个线程上创建新对象,这是确保代码是线程安全的最佳方法之一。

首先。它几乎肯定是安全的,但我仍然会将其锁定

至于你的缓存问题,你在说什么缓存,我能想到的只有CPU缓存,如果我们担心这些缓存是否脏,需要刷新,我们都会遇到很多麻烦

编辑: 从您的评论中,我看到您所指的是CPU缓存


多核和多处理器硬件确保缓存中任何过期的数据都不会被使用。

我想说的是,只要您没有显式地取消引用对象,就不会有空引用的威胁。唯一的时间可能是在初始化myVar之前启动线程2。我认为您不需要d在这个简单的例子中是一个锁。至于你的附带问题,你指的是哪个缓存?

我知道你的问题是关于.NET的,我不能在那里告诉你答案。但是,在Java中,这段代码肯定不安全

风险在于代码重新排序(优化步骤)会在构造函数完成运行之前看到对象引用被更新,因此第二个线程可能会看到第二个对象的部分构造版本

在java中,您可以通过使对象引用易失性或在某种原子引用后面保护它(当然也可以通过同步)来解决这个问题,任何一种原子引用都会设置一个“内存屏障”,限制可以进行的优化,以确保部分构造的对象永远不可见


正如我所说,我对.NET内存模型的了解还不够,不知道.NET是否会出现同样的问题。

是的,我指的是CPU缓存-因此锁区域内的代码确保“缓存干净”?所有代码都是“缓存干净”?这不是我们必须担心的,这是一个硬件问题;)。在任何情况下,线程安全编码可能仍需要进一步的工作才能使“缓存干净”。即使使用单处理器/缓存,其他线程不安全代码也不安全。