Idiom posiadacza inicjalizacji na żądanie

W inżynierii oprogramowania idiom posiadacza inicjalizacji na żądanie ( wzorzec projektowy ) to leniwie ładowany singleton . We wszystkich wersjach Javy ten idiom umożliwia bezpieczną, wysoce współbieżną, leniwą inicjalizację pól statycznych z dobrą wydajnością.

   
      

        
              
    

        
         
    
 public  class  Coś  {  private  Something  ()  {}  private  static  class  LazyHolder  {  static  final  Something  INSTANCE  =  new  Something  ();  }  public  static  Coś  getInstance  ()  {  return  LazyHolder  .  INSTANCJA  ;  }  } 

Implementacja idiomu opiera się na fazie inicjalizacji wykonania w wirtualnej maszynie Java (JVM), zgodnie ze specyfikacją języka Java (JLS). Kiedy klasa Something jest ładowana przez JVM, klasa przechodzi inicjalizację. Ponieważ klasa nie ma żadnych zmiennych statycznych do zainicjowania, inicjalizacja kończy się trywialnie. w niej definicja klasy statycznej LazyHolder nie jest inicjowana, dopóki JVM nie określi, że LazyHolder musi zostać wykonany. Klasa statyczna LazyHolder w klasie Something zostanie wywołana metoda statyczna getInstance , a za pierwszym razem JVM załaduje i zainicjuje klasę LazyHolder . Inicjalizacja LazyHolder powoduje inicjalizację zmiennej statycznej INSTANCE poprzez wykonanie (prywatnego) konstruktora dla klasy zewnętrznej Something . Ponieważ JLS gwarantuje, że faza inicjalizacji klasy będzie sekwencyjna, tj. niewspółbieżna, nie jest wymagana dalsza synchronizacja w statycznym getInstance podczas ładowania i inicjalizacji. A ponieważ faza inicjalizacji zapisuje zmienną statyczną INSTANCE w operacji sekwencyjnej, wszystkie kolejne współbieżne wywołania getInstance zwrócą tę samą poprawnie zainicjowaną INSTANCE bez ponoszenia dodatkowego narzutu synchronizacji.

Zastrzeżenia

Chociaż implementacja jest wydajną, bezpieczną dla wątków „pojedynczą” pamięcią podręczną bez narzutu synchronizacji i lepszą wydajnością niż synchronizacja bez walki, idiomu można używać tylko wtedy, gdy konstrukcja Something gwarantuje, że nie zawiedzie. W większości implementacji JVM, jeśli konstrukcja Something się nie powiedzie, kolejne próby zainicjowania go z tego samego modułu ładującego klasy zakończą się niepowodzeniem NoClassDefFoundError .

Zobacz też

Linki zewnętrzne