gerstla
gerstla

Reputation: 597

Making code thread safe without using the lock statement

I want to call the following code from several threads.

// x is a global/member and initialized to 0
if (Interlocked.Increment(ref x) == 2)
{
   // do something only once
}

This is of course not thread safe: if at run time the first thread is stopped after x was incremented but before the evaluation, and then the second thread increments x so it is now 2, then the if statement is true. Then we return to the first thread and it also gets true in the if statement.

This can be fixed by surrounding the code by the lock statement.

Is there a way to make it thread safe without using the lock statement?

Upvotes: 0

Views: 415

Answers (2)

Ofir Winegarten
Ofir Winegarten

Reputation: 9365

This is of course not thread safe since if at run time the first thread is stopped after x was incremented but before the evaluation. Then the second thread increments and x is know 2 so the if statement is true.Then we return to the first thread and it is know also true.

This is not true.

Interlocked.Increment is an atomic operation no extra lock is required. (otherwise what whould be the point of that?)

The value is being incremented and you get the incremented value. Even if another increment happened afterwards, you still have the first incremented value. so the if will evaluate to false.

Your code for that matter is thread-safe.

Upvotes: 2

Neil
Neil

Reputation: 11919

I think you are incorrect in your assumption. The return value from Interlocked.Increment is the value after the increment, not the value of x at evaluation time. It is entirely possible that x could have been changed by another thread, so the following would be true:

int x = 1;
var y = Interlocked.Increment(ref x);

if(x!=y)

Upvotes: 0

Related Questions