Avoid locking in Singleton

The Singleton is a useful Design Pattern which allows only one instance of your class. Singleton is implemented by declaring static instance of the object reference within the class

class MySingleton {
static MySingleton *instance;
MySingleton() {
//...
}

public:
MySingleton* getInstance() {
return instance;
}

}

static MySingleton::instance= new MySingleton();

If singleton object is created during loading time itself, no locking is required. But in case of lazy loading, it needs to be guarded with a mutex to avoid multiple object instantiation.

MySingleton* getInstance() {

 //acquire mutex
if (NULL == instance) {
instance = new MySingleton();

 }

  //release mutex
return instance;
}

Every request to getInstance() includes mutex overhead.In order to avoid mutex overhead, double checked locking pattern can be used.

// Double-checked locking -- don't use
MySingleton* getInstance() {
if (NULL == instance) {
//acquire mutex
if (NULL==instance) {
instance = new MySingleton();
}
//release mutex
}
}

This method is not 100% safe because of compiler optimizations and may lead to undefined behavior which is hard to debug. Another technique(safe to use) is to use atomic operations and local variable as specified below.


MySingleton* getInstance() {
MySingleton *localRef = new MySingleton();

  int ret = testandset(&instance, 0, localRef);

  //note testandset function returns old value stored in the variable.
if (0==ret) {
return instance;
}
//some other thread had initialized this.

  delete localRef;

  return instance;
}

Advertisements

Symptoms of bad design

Code Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure-Fowler. In order to identify whether legacy software product requires code refactoring, one needs to know whether the existing system design is good or bad. The knowledge of bad design symptom also assists the designer to perform better.

Following are the symptoms of bad design

Rigidity: code/design is hard to change. Simple change requires lot of code changes.

Fragility: code/design is easy to break. code break in unexpected area.

Immobility:Hard to re-use code.

Viscosity:Make easier changes (hack) than fixing issues in-line with the current design.

Complexity: Too much anticipation of future need.

Repetition: Similar code in many places with slight change.

Low Cohesion: Less degree of connectivity among the elements of single class.

High Coupling: Interdependency between modules.