Le design pattern Singleton (reloaded)

En savoir plus

1 : public class Singleton {
2 : private static _instance_;
3 :
4 :      private Singleton(){}
5 :
6 :      public static Singleton getInstance() {
7 :          if (_instance_ == null) {
8 :                synchronized(Singleton.class) {
9 :                     _instance_ = new Singleton();
10 :              }
11 :          }
12 :           return _instance_;
13 :      }
14 : }
 

Synchronisation restreinte à l'appel au constructeur.
Code © Edis Consulting

 

Pour palier à ce problème, on peut envisager une autre solution qui ne synchronise que l'appel au constructeur en ligne 8. Ainsi, on ne payera qu'une seule fois le prix d'une synchronisation. Cela donne le code suivant pour la méthode 'getInstance()' (voir le code ci-contre).

Au premier abord, ce code semble correct. Toutefois il présente le même problème que le premier en environnement multithread. Deux threads peuvent entrer dans le bloc if simultanément, quand '_instance_' est 'null'. Alors que thread1 entre dans le bloc synchronisé pour initialiser '_instance_', Thread2 reste bloqué au 'synchronized'.

Lorsque Thread1 fini son instanciation et libère le 'lock', le Thread2 en attente peut alors entrer à son tour dans ce bloc et initialise une seconde instance de notre Singleton. Nous voyons que l'implémentation de cette méthode n'est pas du tout 'thread safe' et ne doit pas être donc utilisée.


JDN Développeur Envoyer Imprimer Haut de page