java spec 17.3 Sleep and Yield
It is important to note that neither Thread.sleep nor Thread.yield have any synchronization semantics. In particular, the compiler does not have to flush writes cached in registers out to shared memory before a call to Thread.sleep or Thread.yield, nor does the compiler have to reload values cached in registers after a call to Thread.sleep or Thread.yield.
For example, in the following (broken) code fragment, assume that this.done is a nonvolatile boolean field:
while (!this.done) Thread.sleep(1000);
The compiler is free to read the field this.done just once, and reuse the cached value in each execution of the loop. This would mean that the loop would never terminate, even if another thread changed the value of this.done.
Question: is it same in C#?
as we know, we can add Thread.MemoryBarrier(); to fix the issue.
while(this.done)
{
Thread.MemoryBarrier();
Thread.sleep(1000);
}
Question: But is Compiler able to identify fun() as MemoryBarrier in following case?
public static void fun()
{
Thread.MemoryBarrier();
}
while(this.done)
{
fun();
Thread.sleep(1000);
}
if it's ok, why it doesn't identify sleep as MemoryBarrier since it can't make sure whether sleep contain MemoryBarrier?
Since
Sleep
does not explicitly claim to have any such semantic, the only safe answer is "don't rely on it having any such semantic". There are plenty of ways of safely polling a variable or checking some other token (personally I'd be tempted to look at aMonitor.Wait(obj, timeout)
, but YMMV). You say:Since the
Sleep
method does not claim to do this, you cannot rely on it. It could be that the designers actively disagree with you; it could be that it never even came up for discussion (after all, that is a fairly arbitrary effect).