我已经被认为如果多个线程可以访问变量,那么所有对该变量的读取和写入都必须受到同步代码的保护,例如"lock"语句,因为处理器可能会在中途切换到另一个线程写.
但是,我正在使用Reflector查看System.Web.Security.Membership并找到如下代码:
public static class Membership
{
private static bool s_Initialized = false;
private static object s_lock = new object();
private static MembershipProvider s_Provider;
public static MembershipProvider Provider
{
get
{
Initialize();
return s_Provider;
}
}
private static void Initialize()
{
if (s_Initialized)
return;
lock(s_lock)
{
if (s_Initialized)
return;
// Perform initialization...
s_Initialized = true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么s_Initialized字段在锁外读取?另一个线程难道不能同时写入它吗?变量的读写是否是原子的?
我写了这个小程序:
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(WriteX);
t.Start();
for (int i = 0; i < 1000; i++)
{
Console.Write("O");
}
}
private static void WriteX()
{
for (int i = 0; i < 1000; i++)
{
Console.Write(".");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我跑了大约五十次,控制台上的第一个字符总是"O".这对我来说很奇怪,因为t线程首先启动然后主要继续.
这有什么解释吗?
我正在寻找一个可重现的示例,可以演示volatile关键字的工作原理.我正在寻找一些工作"错误"的东西,而没有标记为易变的变量,并且"正确"地使用它.
我的意思是一些示例,它将证明执行期间的写/读操作顺序与变量未标记为volatile时的预期顺序不同,并且当变量未标记为volatile时不同.
我认为我得到了一个例子但是在其他人的帮助下我意识到它只是一段错误的多线程代码.为什么volatile和MemoryBarrier不会阻止操作重新排序?
我还发现了一个链接,它演示了volatile对优化器的影响,但它与我正在寻找的不同.它表明对标记为volatile的变量的请求不会被优化.如何在C#中说明volatile关键字的用法
这是我到目前为止的地方.此代码未显示任何读/写操作重新排序的迹象.我正在寻找一个会展示的.
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
namespace FlipFlop
{
class Program
{
//Declaring these variables
static byte a;
static byte b;
//Track a number of iteration that it took to detect operation reordering.
static long iterations = 0;
static object locker = new object();
//Indicates that operation reordering is not found yet.
static volatile bool continueTrying = true;
//Indicates that Check method should continue.
static volatile bool continueChecking = true;
static …Run Code Online (Sandbox Code Playgroud)