I am writing simple bank account tutorial program. For each new customer which enrolls, the account number will be incremented by 1, for a new id.
I saw example in "C# Mueller" book. I am just curious if this is proper way to conduct this, how will it handle concurrency enrollments? Is there a better to handle this, maybe with Singletons or global variables, memory cache? How would item like this be handled in real world application?
public class BankAccount
{
private static int _nextAccountNumber = 1000;
private int _accountNumber;
private double _balance;
public void InitBankAccount()
{
_accountNumber = ++_nextAccountNumber;
_balance = 0.0;
}
public void Deposit(decimal amount)
{
_balance += amount;
}
etc...
This site is also useful: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement
You can actually use Interlocked.Increment here, which returns the incremented amount. It should be thread safe, there's an example in the docs link that uses it for that purpose.
using System.Threading;
...
public void InitBankAccount()
{
_accountNumber = Interlocked.Increment(ref _nextAccountNumber);
_balance = 0.0;
}
What you are doing is ok, but not thread safe. thepirat000 mentioned in a comment that you could use a lock statement.
private static object acctNumLock = new object();
…
lock(acctnumLock) {
_accountNumber = ++_nextAccountNumber;
}
You should also consider using the Interlock.Increment method which is more efficient. The lock statement allows you to 'lock' (allow only one thread access at a time) to a block of statements. The Interlock.Increment is an atomic operation, that only does one thing (namely increment a value), but does so in a way that ensures the operation is completed before the thread switches. Both provide thread safety.
Is there a better way? That's a very difficult question to answer because it depends on what you are trying to do. I suspect that actual banking applications take out DB locks and use specific algorithms to generate account numbers (i.e. a much more complicated process). If you are just trying to generate unique values for simple applications what you have should work fine.
Related
Say, I have a static class like this
static class PCstatus
{
public static class Cpu
{
//CPU loads
public static int lt;
public static int l1;
public static int l2;
public static int l3;
public static int l4;
//CPU Temp
public static double t0;
//Frequency
}}
Which I'm using as a storage space(should I be doing that?)
And I have 5-6 threads that periodically change different variables in this class(Note: No two threads change the same value) i.e:
First thread:
PCstatus.lt = 0;,
thread.sleep(1000);
Second
PCstatus.l1 = 0;,
thread.sleep(1000);
And then I have another thread that periodically reads all the values from the class, parse them and send them over serial.
Is this a sane way to do it? There is no locking mechanism in the class, so theoretically, one of the threads could try to change a var while the final thread is reading it.
I'm not sure if such a thing can happen, I've run this program for days. So far, haven't noticed any strange behavior.
I can implement a locking mechanism to the class. (bool _isBeingUsed) and make the threads check that value before performing any operation, but I'm not sure if it's necessary.
I know the proper way to output values from threads is to use delegates, but if it's not really necessary, I could do without the added complexity they bring.
Reads and writes to int values in C# are atomic, so you'll never have to worry about data shearing.
However, writing to multiple values within the class is not atomic, so in your example:
First thread:
PCstatus.lt = 0;
thread.sleep(1000);
Second
PCstatus.l1 = 0;
thread.sleep(1000);
There's no guarantee that just because thread 3 sees that lt is 0 that it will also see that l1 is zero. You've potentially got data race issues here.
Also, just because a thread writes to a variable it doesn't mean that other threads will see its value immediately. Instruction reordering of instructions, compiler reordering of instructions and CPU caching strategies may conspire to prevent the write making its way back to main memory and into another thread.
If you're only ever going to change single values from a thread then use methods on the Interlocked class to ensure that your changes are visible across threads. They use a memory barrier to ensure that read/writes to variables propagate across threads.
If you're going to write multiple values in one hit, or if you want to read multiple values in one hit then you'll need to use a lock.
No locking is required, but you should declare those fields volatile to ensure that updates from one thread can be picked up immediately by other threads.
See: https://msdn.microsoft.com/en-us/library/x13ttww7.aspx
Note that you can't declare a double to be volatile. I think for your application you could probably just use a float instead. Otherwise you can use a class that contains an immutable double value.
And I have 5-6 threads that periodically change different variables in this class
Instead of having single storage for results of 5-6 workers you can supply each worker with event. Then anyone who need results can subscribe to it and create local storage, means no thread issues anymore.
Something like
public static class CPUStats
{
public static EventHandler<CPUEventArgs> Measured;
public static CPUStats()
{
Task.Factory.StartNew(() =>
{
while(true)
{
... // poll CPU data periodically
Measured?.Invoke(null, new CPUEventArgs() { LT = lt, L1 = l1, ... });
}
}, TaskCreationOptions.LongRunning);
}
}
public static class StatsWriter
{
static int lt;
static int l1;
...
public static StatsWriter()
{
CPUStats.Measured += (s, e) =>
{
lt = e.LT;
l1 = e.L1;
}
}
public static void Save()
{
var text = $"{DateTime.Now} CPU[{lt},{l1}...]";
... // save text
}
}
I am trying to create thread safe properties in C# and I want to make sure that I am on the correct path - here is what I have done -
private readonly object AvgBuyPriceLocker = new object();
private double _AvgBuyPrice;
private double AvgBuyPrice
{
get
{
lock (AvgBuyPriceLocker)
{
return _AvgBuyPrice;
}
}
set
{
lock (AvgBuyPriceLocker)
{
_AvgBuyPrice = value;
}
}
}
Reading this posting, it would seem as if this isn't the correct way of doing it -
C# thread safety with get/set
however, this article seems to suggest otherwise,
http://www.codeproject.com/KB/cs/Synchronized.aspx
Does anybody have a more definitive answer?
Edit:
The reason that I want to do the Getter/Setter for this property is b/c I actually want it to fire an event when it is set - so the code would actually be like this -
public class PLTracker
{
public PLEvents Events;
private readonly object AvgBuyPriceLocker = new object();
private double _AvgBuyPrice;
private double AvgBuyPrice
{
get
{
lock (AvgBuyPriceLocker)
{
return _AvgBuyPrice;
}
}
set
{
lock (AvgBuyPriceLocker)
{
Events.AvgBuyPriceUpdate(value);
_AvgBuyPrice = value;
}
}
}
}
public class PLEvents
{
public delegate void PLUpdateHandler(double Update);
public event PLUpdateHandler AvgBuyPriceUpdateListener;
public void AvgBuyPriceUpdate(double AvgBuyPrice)
{
lock (this)
{
try
{
if (AvgBuyPriceUpdateListener!= null)
{
AvgBuyPriceUpdateListener(AvgBuyPrice);
}
else
{
throw new Exception("AvgBuyPriceUpdateListener is null");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
I am pretty new to making my code thread safe so please feel free to tell me if I am going about it in the totally wrong way!
Will
The locks, as you have written them are pointless. The thread reading the variable, for example, will:
Acquire the lock.
Read the value.
Release the lock.
Use the read value somehow.
There is nothing to stop another thread from modifying the value after step 3. As variable access in .NET is atomic (see caveat below), the lock is not actually achieving much here: merely adding an overhead. Contrast with the unlocked example:
Read the value.
Use the read value somehow.
Another thread may alter the value between step 1 and 2 and this is no different to the locked example.
If you want to ensure state does not change when you are doing some processing, you must read the value and do the processing using that value within the contex of the lock:
Acquire the lock.
Read the value.
Use the read value somehow.
Release the lock.
Having said that, there are cases when you need to lock when accessing a variable. These are usually due to reasons with the underlying processor: a double variable cannot be read or written as a single instruction on a 32 bit machine, for example, so you must lock (or use an alternative strategy) to ensure a corrupt value is not read.
Since you have a primitive value this locking will work fine - the issue in the other question was that the property value was a more complex class (a mutable reference type) - the locking will protect accessing and retrieving the instance of the double value held by your class.
If your property value is a mutable reference type on the other hand locking will not protect from changing the class instance once retrieved using its methods, which is what the other poster wanted it to do.
Thread safety is not something you should add to your variables, it is something you should add to your "logic". If you add locks to all your variables, your code will still not necessarily be thread safe, but it will be slow as hell.
To write a thread-safe program, Look at your code and decide where multiple threads could be using the same data/objects. Add locks or other safety measures to all those critical places.
For instance, assuming the following bit of pseudo code:
void updateAvgBuyPrice()
{
float oldPrice = AvgBuyPrice;
float newPrice = oldPrice + <Some other logic here>
//Some more new price calculation here
AvgBuyPrice = newPrice;
}
If this code is called from multiple threads at the same time, your locking logic has no use. Imagine thread A getting AvgBuyPrice and doing some calculations. Now before it is done, thread B is also getting the AvgBuyPrice and starting calculations. Thread A in the meantime is done and will assign the new value to AvgBuyPrice. However, just moments later, it will be overwritten by thread B (which still used the old value) and the work of thread A has been lost completely.
So how do you fix this? If we were to use locks (which would be the ugliest and slowest solution, but the easiest if you're just starting with multithreading), we need to put all the logic which changes AvgBuyPrice in locks:
void updateAvgBuyPrice()
{
lock(AvgBuyPriceLocker)
{
float oldPrice = AvgBuyPrice;
float newPrice = oldPrice + <Some other code here>
//Some more new price calculation here
AvgBuyPrice = newPrice;
}
}
Now, if thread B wants to do the calculations while thread A is still busy, it will wait until thread A is done and then do its work using the new value. Keep in mind though, that any other code that also modifies AvgBuyPrice should also lock AvgBuyPriceLocker while it's working!
Still, this will be slow if used often. Locks are expensive and there are a lot of other mechanism to avoid locks, just search for lock-free algorithms.
Reading and writing of doubles is atomic anyway (source) reading and writing of doubles isn't atomic and so it would be necessary to protect access to a double using a lock, however for many types reading and writing is atomic and so the following would be just as safe:
private float AvgBuyPrice
{
get;
set;
}
My point is that thread safety is more complex than simply protecting each of your properties. To give a simple example suppose I have two properties AvgBuyPrice and StringAvgBuyPrice:
private string StringAvgBuyPrice { get; set; }
private float AvgBuyPrice { get; set; }
And suppose I update the average buy price thusly:
this.AvgBuyPrice = value;
this.StringAvgBuyPrice = value.ToString();
This clearly isn't thread safe and individually protecting properties in the above way won't help at all. In this case the locking should be performed at a different level rather than at a per-property level.
Although an old question, it gets on top of Google searches, so I add a reply. In you example, the get locker will not be released after return. Therefore, I suggest to use the ReaderWriterLockSlim within a try-finally block in such a case, which is very well suitable for the result you try to accomplish. It allows multiple threads for reading or exclusive access for writing:
private readonly ReaderWriterLockSlim AvgBuyPriceLocker = new ReaderWriterLockSlim();
private double _AvgBuyPrice = 0;
public double AvgBuyPrice {
get {
AvgBuyPriceLocker.EnterReadLock();
try { return _AvgBuyPrice; }
finally { AvgBuyPriceLocker.ExitReadLock(); }
}
set {
AvgBuyPriceLocker.EnterWriteLock();
try { _AvgBuyPrice = value; }
finally { AvgBuyPriceLocker.ExitWriteLock(); }
}
}
Is there any reason why you would create locks around the getter and setter of a boolean property like this?
private _lockObject = new object();
private bool _myFlag;
public bool MyFlag
{
get
{
lock (_lockObject)
{
return _myFlag;
}
}
set
{
lock (_lockObject)
{
_myFlag = value;
}
}
}
Well, you don't need locks necessarily - but if you want one thread to definitely read the value that another thread has written, you either need locks or a volatile variable.
I've personally given up trying to understand the precise meaning of volatile. I try to avoid writing my own lock-free code, instead relying on experts who really understand the memory model.
EDIT: As an example of the kind of problem this can cause, consider this code:
using System;
using System.Threading;
public class Test
{
private static bool stop = false;
private bool Stop
{
get { return stop; }
set { stop = value; }
}
private static void Main()
{
Thread t = new Thread(DoWork);
t.Start();
Thread.Sleep(1000); // Let it get started
Console.WriteLine("Setting stop flag");
Stop = true;
Console.WriteLine("Set");
t.Join();
}
private static void DoWork()
{
Console.WriteLine("Tight looping...");
while (!Stop)
{
}
Console.WriteLine("Done.");
}
}
That program may or may not terminate. I've seen both happen. There's no guarantee that the "reading" thread will actually read from main memory - it can put the initial value of stop into a register and just keep using that forever. I've seen that happen, in reality. It doesn't happen on my current machines, but it may do on my next.
Putting locks within the property getter/setter as per the code in the question would make this code correct and its behaviour predictable.
For more on this, see this blog post by Eric Lippert.
Reads and writes of bool are atomic.
However the name "flag" indicates that separate threads will be reading/writing until some condition occurred. To avoid unexpected behavior due to optimization you should consider adding the volatile keyword to you bool declaration.
There's no reason to have a lock right there.
Taking a lock may well be appropriate in your design, but it's very doubtful that this is the right granularity.
You need to make your design thread-safe, not individual properties (or even entire objects).
I am trying to learn the threading in C#. Today I sow the following code at http://www.albahari.com/threading/:
class ThreadTest
{
bool done;
static void Main()
{
ThreadTest tt = new ThreadTest(); // Create a common instance
new Thread (tt.Go).Start();
tt.Go();
}
// Note that Go is now an instance method
void Go()
{
if (!done) { done = true; Console.WriteLine ("Done"); }
}
}
In Java unless you define the "done" as volatile the code will not be safe. How does C# memory model handles this?
Guys, Thanks all for the answers. Much appreciated.
Well, there's the clear race condition that they could both see done as false and execute the if body - that's true regardless of memory model. Making done volatile won't fix that, and it wouldn't fix it in Java either.
But yes, it's feasible that the change made in one thread could happen but not be visible until in the other thread. It depends on CPU architecture etc. As an example of what I mean, consider this program:
using System;
using System.Threading;
class Test
{
private bool stop = false;
static void Main()
{
new Test().Start();
}
void Start()
{
new Thread(ThreadJob).Start();
Thread.Sleep(500);
stop = true;
}
void ThreadJob()
{
int x = 0;
while (!stop)
{
x++;
}
Console.WriteLine("Counted to {0}", x);
}
}
While on my current laptop this does terminate, I've used other machines where pretty much the exact same code would run forever - it would never "see" the change to stop in the second thread.
Basically, I try to avoid writing lock-free code unless it's using higher-level abstractions provided by people who really know their stuff - like the Parallel Extensions in .NET 4.
There is a way to make this code lock-free and correct easily though, using Interlocked. For example:
class ThreadTest
{
int done;
static void Main()
{
ThreadTest tt = new ThreadTest(); // Create a common instance
new Thread (tt.Go).Start();
tt.Go();
}
// Note that Go is now an instance method
void Go()
{
if (Interlocked.CompareExchange(ref done, 1, 0) == 0)
{
Console.WriteLine("Done");
}
}
}
Here the change of value and the testing of it are performed as a single unit: CompareExchange will only set the value to 1 if it's currently 0, and will return the old value. So only a single thread will ever see a return value of 0.
Another thing to bear in mind: your question is fairly ambiguous, as you haven't defined what you mean by "thread safe". I've guessed at your intention, but you never made it clear. Read this blog post by Eric Lippert - it's well worth it.
No, it's not thread safe. You could potentially have one thread check the condition (if(!done)), the other thread check that same condition, and then the first thread executes the first line in the code block (done = true).
You can make it thread safe with a lock:
lock(this)
{
if(!done)
{
done = true;
Console.WriteLine("Done");
}
}
Even in Java with volatile, both threads could enter the block with the WriteLine.
If you want mutual exclusion you need to use a real synchronisation object such as a lock.
onle way this is thread safe is when you use atomic compare and set in the if test
if(atomicBool.compareAndSet(false,true)){
Console.WriteLine("Done");
}
You should do something like this:
class ThreadTest{
Object myLock = new Object();
...
void Go(){
lock(myLock){
if(!done)
{
done = true;
Console.WriteLine("Done");
}
}
}
The reason you want to use an generic object, rather than "this", is that if your object (aka "this") changes at all it is considered another object. Thus your lock does not work any more.
Another small thing you might consider is this. It is a "good practices" thing, so nothing severe.
class ThreadTest{
Object myLock = new Object();
...
void Go(){
lock(myLock){
if(!done)
{
done = true;
}
}
//This line of code does not belong inside the lock.
Console.WriteLine("Done");
}
Never have code inside a lock that does not need to be inside a lock. This is due to the delay this causes. If you have lots of threads you can gain a lot of performance from removing all this unnecessary waiting.
Hope it helps :)
I have a C# singleton class that multiple classes use. Is access through Instance to the Toggle() method thread-safe? If yes, by what assumptions, rules, etc. If no, why and how can I fix it?
public class MyClass
{
private static readonly MyClass instance = new MyClass();
public static MyClass Instance
{
get { return instance; }
}
private int value = 0;
public int Toggle()
{
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
return value;
}
}
Is access through 'Instance' to the 'Toggle()' class threadsafe? If yes, by what assumptions, rules, etc. If no, why and how can I fix it?
No, it's not threadsafe.
Basically, both threads can run the Toggle function at the same time, so this could happen
// thread 1 is running this code
if(value == 0)
{
value = 1;
// RIGHT NOW, thread 2 steps in.
// It sees value as 1, so runs the other branch, and changes it to 0
// This causes your method to return 0 even though you actually want 1
}
else if(value == 1)
{
value = 0;
}
return value;
You need to operate with the following assumption.
If 2 threads are running, they can and will interleave and interact with eachother randomly at any point. You can be half way through writing or reading a 64 bit integer or float (on a 32 bit CPU) and another thread can jump in and change it out from underneath you.
If the 2 threads never access anything in common, it doesn't matter, but as soon as they do, you need to prevent them from stepping on each others toes. The way to do this in .NET is with locks.
You can decide what and where to lock by thinking about things like this:
For a given block of code, if the value of something got changed out from underneath me, would it matter? If it would, you need to lock that something for the duration of the code where it would matter.
Looking at your example again
// we read value here
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
// and we return it here
return value;
In order for this to return what we expect it to, we assume that value won't get changed between the read and the return. In order for this assumption to actually be correct, you need to lock value for the duration of that code block.
So you'd do this:
lock( value )
{
if(value == 0)
... // all your code here
return value;
}
HOWEVER
In .NET you can only lock Reference Types. Int32 is a Value Type, so we can't lock it.
We solve this by introducing a 'dummy' object, and locking that wherever we'd want to lock 'value'.
This is what Ben Scheirman is referring to.
The original impplementation is not thread safe, as Ben points out
A simple way to make it thread safe is to introduce a lock statement. Eg. like this:
public class MyClass
{
private Object thisLock = new Object();
private static readonly MyClass instance = new MyClass();
public static MyClass Instance
{
get { return instance; }
}
private Int32 value = 0;
public Int32 Toggle()
{
lock(thisLock)
{
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
return value;
}
}
}
I'd also add a protected constructor to MyClass to prevent the compiler from generating a public default constructor.
That is what I thought. But, I I'm
looking for the details... 'Toggle()'
is not a static method, but it is a
member of a static property (when
using 'Instance'). Is that what makes
it shared among threads?
If your application is multi-threaded and you can forsee that multiple thread will access that method, that makes it shared among threads. Because your class is a Singleton you know that the diferent thread will access the SAME object, so be cautioned about the thread-safety of your methods.
And how does this apply to singletons
in general. Would I have to address
this in every method on my class?
As I said above, because its a singleton you know diferent thread will acess the same object, possibly at the same time. This does not mean you have to make every method obtain a lock. If you notice that a simultaneos invocation can lead to corrupted state of the class, then you should apply the method mentioned by #Thomas
Can I assume that the singleton pattern exposes my otherwise lovely thread-safe class to all the thread problems of regular static members?
No. Your class is simply not threadsafe. The singleton has nothing to do with it.
(I'm getting my head around the fact that instance members called on a static object cause threading problems)
It's nothing to do with that either.
You have to think like this: Is it possible in my program for 2 (or more) threads to access this piece of data at the same time?
The fact that you obtain the data via a singleton, or static variable, or passing in an object as a method parameter doesn't matter. At the end of the day it's all just some bits and bytes in your PC's RAM, and all that matters is whether multiple threads can see the same bits.
Your thread could stop in the middle of that method and transfer control to a different thread. You need a critical section around that code...
private static object _lockDummy = new object();
...
lock(_lockDummy)
{
//do stuff
}
I was thinking that if I dump the singleton pattern and force everyone to get a new instance of the class it would ease some problems... but that doesn't stop anyone else from initializing a static object of that type and passing that around... or from spinning off multiple threads, all accessing 'Toggle()' from the same instance.
Bingo :-)
I get it now. It's a tough world. I wish I weren't refactoring legacy code :(
Unfortunately, multithreading is hard and you have to be very paranoid about things :-)
The simplest solution in this case is to stick with the singleton, and add a lock around the value, like in the examples.
Quote:
if(value == 0) { value = 1; }
if(value == 1) { value = 0; }
return value;
value will always be 0...
Well, I actually don't know C# that well... but I am ok at Java, so I will give the answer for that, and hopefully the two are similar enough that it will be useful. If not, I apologize.
The answer is, no, it's not safe. One thread could call Toggle() at the same time as the other, and it is possible, although unlikely with this code, that Thread1 could set value in between the times that Thread2 checks it and when it sets it.
To fix, simply make Toggle() synchronized. It doesn't block on anything or call anything that might spawn another thread which could call Toggle(), so that's all you have to do save it.