Historisch gezien is lazy initialization ontstaan om het gebruik van middelen te optimaliseren, waarbij een object alleen wordt gemaakt wanneer het echt nodig is. Dit was oorspronkelijk belangrijk bij het werken met zware objecten, verbindingen, caches of bij het implementeren van complexe patronen (bijvoorbeeld Singleton).
Het probleem is dat als je alle middelen direct aanmaakt, je onnodig veel geheugen, tijd en kracht kunt verspillen, zelfs wanneer het object niet nodig is. Lazy initialization lost de taak van "uitgestelde" creatie op.
De oplossing wordt meestal geïmplementeerd door te controleren: als het object nog niet is gemaakt, maken we het aan, anders retourneren we het bestaande.
Voorbeeldcode:
public class LazyHolder { private Resource resource; public Resource getResource() { if (resource == null) { resource = new Resource(); } return resource; } }
In multithreadomstandigheden is synchronisatie noodzakelijk.
Belangrijke kenmerken:
Is Double-Checked Locking een betrouwbare implementatie voor lazy initialization van Singleton?
Pas sinds Java 5, omdat de geheugenmodel dit eerder niet garandeerde. Het is noodzakelijk om het sleutelwoord volatile voor het resourceveld te gebruiken.
private volatile Resource resource; public Resource getResource() { if (resource == null) { synchronized(this) { if (resource == null) { resource = new Resource(); } } } return resource; }
Heeft het zin om lazy initialization te doen voor lichte objecten?
Over het algemeen niet. Het is beter om "lichte" objecten onmiddellijk te maken, om de leesbaarheid van de code niet te verkorten en de extra logica niet te compliceren.
Werkt lazy initialization bij serialisatie van objecten?
Niet altijd. Bij serialisatie kan het "oude" staat worden hersteld, of is extra logica in readObject() nodig.
In een high-load service werd een speciale objectpool lui geparsed, maar niet gesynchroniseerd. Twee threads initialiseerden tegelijkertijd het object, wat leidde tot geheugenlekken en onvoorspelbare fouten.
Voordelen:
Nadelen:
In een grote webapplicatie wordt de analytica alleen aangesloten via een API-aanroep door een lazy geïnitialiseerd proxy-object met double-checked locking.
Voordelen:
Nadelen: