I have the following class
class Singleton
{
private:
static Singleton *p_inst;
Singleton();
public:
static Singleton * instance()
In multi-threading that clause
if(!p_inst)
{
p_inst = new Singleton();
}
is actually 3 separate actions. You are getting the value of p_inst
, setting the value of p_inst
and writing the value of p_inst
. So get-set-write means that you need to put a lock around p_inst
otherwise you can have 2 threads which create a Singleton
value that each thread uses.
Here is how you can view the issue, assume that your Singleton
has a mutable field val
:
thread A -> p_inst is NULL
thread B -> p_inst is NULL
thread A -> set to Singleton (1)
thread B -> set to Singleton (2)
thread C -> p_inst is Singleton (2)
thread A -> set val to 4
thread B -> set val to 6
thread C -> get val (it's 6)
thread A -> get val (it's 4!!)
You see? There's 2 copies of a Singleton floating about, neither of which knows about the other. The third thread which checks on the Singleton
is only going to see the last assignment. But with locking, you can prevent multiple assignment and these types of problems.