user981225
user981225

Reputation: 9252

Avoiding duplicate if statements inside and outside a lock

The below code is a very simplified example of what I am trying to accomplish.

 private object _highestLevelLock = new object();
    private int _highestValue;
    private void SetHighestValue()
    {
        var random = new Random();
        var next = random.Next(0, 100);
        if (next > _highestValue)
        {
            lock (_highestLevelLock)
            {
                if(next > _highestValue)
                    _highestValue = next;
            }
        }
    }

Namely, I have a variable that holds the highest integer that I have come across so far. SetHighestValue() can be accessed by multiple threads.

If the random integer generated is larger than the currently largest integer, I will update the _highestValue.

My question is, how can I avoid checking twice if next > highestValue? If I remove it from inside the lock, then there is the risk that _highestValue will get set to something even higher, before this thread sets the value, and in this scenario, _highestValue will be inaccurate.

I know that I can get rid of the if statement outside the lock, but I do not want to lock unnecessarily.

Is there a better way to accomplish this? Potentially some combination of locking and/or using the Interlocked namespace?

On a somewhat related note, should _highestValue be volatile? Even if so, I assume that will not help with my question at hand.

Thanks!

Upvotes: 1

Views: 336

Answers (2)

Lee
Lee

Reputation: 144136

I think you can use the Interlocked class instead of locking: Each thread with a higher value tries to perform the update, but re-checks if it fails:

var next = random.Next(0, 100);
int current = _highestValue;
bool updated = false;
while(next > current && !updated)
{
    updated = Interlocked.Exchange(ref _highestValue, next, current);
    current = _highestValue;
}

Upvotes: 1

CrazyCasta
CrazyCasta

Reputation: 28302

What you are describing is a case of test and test and set and is a very efficient way of handling things. To answer your question, short of encapsulating your condition in a function there is no way to get rid of the code duplication.

Upvotes: 2

Related Questions