两个线程,线程1,将变量g__value++,然后 触发事件,sleep(500).线程2,接收事件,打印变量值。 很简单的一个小程序,但我发现 先SetEvent()与先Sleep(),出来的结果不一样。
DWORD WINAPI ThreadSend(LPCVOID pParam)
{
while(1)
{
//InterlockedIncrement((LPLONG)&g_value);
g_value++;
SetEvent(g_hEvent);
Sleep(500); //这两条语句顺序相反,先sleep再发信号则,没有g_value=1的情况
}
return 0;
}
DWORD WINAPI ThreadRecv(LPCVOID pParam)
{
while(1)
{
WaitForSingleObject( g_hEvent,INFINITE);
printf("g_value:%d\n",g_value);
//ResetEvent(g_hEvent);
}
return 0;
}
执行结果是
g_value=0
g_value=1
g_value=2
g_value=3
但是,先sleep再SetEvent(),结果是
g_value=0
g_value=2
g_value=3
g_value=4
就是没有1 这是为什么呢?
volitile取消g_value的优化,定义的地方
volitile取消g_value的优化,定义的地方
@ oyljerry
加了volitile还是不行哦,优化的话,也不可能只优化1啊,后面的都没有差错,没有漏的。
java中关键字volatile的作用
用在多线程,同步变量。 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B。只在某些动作时才进行A和B的同步。因此存在A和B不一致的情况。volatile就是用来避免这种情况的。volatile告诉jvm, 它所修饰的变量不保留拷贝,直接访问主内存中的(也就是上面说的A)
在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器)。为了性能,一个线程会在自己的memory中保持要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory中的值,或者main memory中的值不一致的情况。
如private volatile boolean pleaseStop;