简体   繁体   中英

lock vs Interlocked.Exchange

I have an application which constantly (+-100ms) reads orders from a PLC and then puts them in a model which then gets read by multiple clients. For this im using the lock statement.

Order Reading thread :

lock (model) {
//update object
}

Clients Reading :

lock (model) {
//serialize object to json string
}
send over tcp stream to client.

But i could also use for the update :

Interlocked.ExChange(oldObj, newObj)

I don't want my clients to have to wait for a lock that is happening in the Order Reading thread. And i definitly dont want client to block my Order Reading thread.

Am i better off using the Interlocked ?

Thanks for the advice!

Yes, you are better off using Interlocked as it's more efficient since it's mostly translated into a single atomic operation.

However, if you don't mind the clients still reading the old object for a bit you can even do without the Interlocked and just set a new instance.

The client that happen to get the new instance will get the updated data and those that don't will get it in one of the next checks.

If your single producer is creating a brand new model, and assigning it to a shared field, then yes, Interlocked.Exchange is the way to go here.

If your producer does not need to know what the old model was, then you could use Volatile.Write(ref _sharedObj, newObj) instead to keep it simpler.

Just be aware of 3 things:

  1. Use Volatile.Read to read your shared object.
  2. The consumers should read the shared state once per unit of work

     //incorrect - _sharedObj is not guaranteed to be the same in both reads var x = CalculateX(_sharedObj); var y = CalculateY(_sharedObj); //correct var obj = Volatile.Read(ref _sharedObj); var x = CalculateX(obj); var y = CalculateY(obj); 
  3. The consumers will sometimes be using a slightly outdated model. So be sure that using a slightly outdated object doesn't cause you any trouble

     var obj = _sharedObj; // If _sharedObj is exchanged here, then `obj` will be outdated var x = CalculateX(obj); var y = CalculateY(obj); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM