Does Sleep not have synchronization semantic?

246 Views Asked by At

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?

1

There are 1 best solutions below

5
On BEST ANSWER

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 a Monitor.Wait(obj, timeout), but YMMV). You say:

I just think sleep and other function should be identified as MemoryBarrier.

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).