مقداردهی اولیه کاهلانه

در برنامه نویسی کامپیوتری، مقداردهی اولیهٔ کاهلانه (به انگلیسی: Lazy Initialization) یک الگو برای به تأخیر انداختن ساخت یک شیء می‌باشد، به طوری که محاسبه و ایجاد شیء مورد نظر تا زمانی که به آن شیء نیازی نباشد معوق می‌شود. این الگو زمانی استفاده می‌شود که ساخت شیء از نظر هزینهٔ محاسبه‌گران می‌باشد و اجرای برنامه در گرو ساخته شدن آن شیء نمی‌باشد. بدین ترتیب برنامه روال عادی اجرای خود را با سرعت بیشتری طی می‌کند و تنها وقتی به ساختن آن شیء می‌پردازد که به‌طور مستقیم به آن نیازمند بشود. برای مثال تا وقتی که در برنامه نیاز به ارتباط به پایگاه داده‌ها نداریم شیء اتصال دهنده به پایگاه داده‌ها را نمی‌سازیم و از هزینه‌های محاسباتی ساخت چنین شیء ای اجتناب می‌کنیم، ولی به محض اینکه در این برنامه خواستیم به پایگاه داده‌ها متصل بشویم، برنامهٔ ما شیء اتصال را ساخته و از آن استفاده می‌کند.
معمولاً برای پیاده‌سازی این الگو از یک متغیر کمکی استفاده می‌کنند که می‌تواند ۲ حالت به خود بگیرد. حالت صفر به این معنا می‌باشد که پروسهٔ ساخت شیء هنوز رخ نداده و حالت یک یعنی این که این پروسه اجرا شده و شیء قبلاً ساخته شده. هر بار که برنامه به شیء مورد نطر ارجاع می‌دهد، با چک کردن این متغیر کمکی می‌فهمیم که آیا شیء تا آلان ساخته شده یا نه. اگر شیء ساخته شده بود که می‌توان از همان برای ادامهٔ اجرای برنامه استفاده کنیم، در غیر این صورت بایستی ابتدا شی را ساخته و مقدار دهی کرده و سپس مقدار متغیر کمکی را برابر یک قرار دهیم.
بایستی توجه داشته باشیم که در یک کد چندریسمانی دسترسی به این متغیر کمکی بایستی به صورت سنکرون باشد تا حالت مسابقه پیش نیاید.

Java

import java.util.HashMap;import java.util.Map;import java.util.Map.Entry;public enum FRUIT_TYPE {NONE,APPLE,BANANA,}class Program {/** * @param args */public static void main(String[] args) {Fruit.getFruitByTypeName(FRUIT_TYPE.BANANA);Fruit.showAll();Fruit.getFruitByTypeName(FRUIT_TYPE.APPLE);Fruit.showAll();Fruit.getFruitByTypeName(FRUIT_TYPE.BANANA);Fruit.showAll();}}public class Fruit {private static Map<FRUIT_TYPE, Fruit> types = new HashMap<>();/** * Using a private constructor to force the use of the factory method. * @param type */private Fruit(FRUIT_TYPE type) {}/** * Lazy Factory method, gets the Fruit instance associated with a certain * type. Instantiates new ones as needed. * @param type Any allowed fruit type, e.g. APPLE * @return The Fruit instance associated with that type. */public static Fruit getFruitByTypeName(FRUIT_TYPE type) {Fruit fruit;
                // This has concurrency issues.  Here the read to types is not synchronized,
                // so types.put and types.containsKey might be called at the same time.
                // Don't be surprised if the data is corrupted.if (!types.containsKey(type)) {// Lazy initialisationfruit = new Fruit(type);types.put(type, fruit);} else {// OK, it's available currentlyfruit = types.get(type);}return fruit;}/** * Lazy Factory method, gets the Fruit instance associated with a certain  * type. Instantiates new ones as needed. Uses double-checked locking * pattern for using in highly concurrent environments. * @param type Any allowed fruit type, e.g. APPLE * @return The Fruit instance associated with that type. */public static Fruit getFruitByTypeNameHighConcurrentVersion(FRUIT_TYPE type) {if (!types.containsKey(type)) {synchronized (types) {// Check again, after having acquired the lock to make sure// the instance was not created meanwhile by another threadif (!types.containsKey(type)) {// Lazy initialisationtypes.put(type, new Fruit(type));}}}return types.get(type);}/** * Displays all entered fruits. */public static void showAll() {if (types.size() > 0) {System.out.println("Number of instances made = " + types.size());for (Entry<FRUIT_TYPE, Fruit> entry : types.entrySet()) {System.out.println(Constants.firstLetterToUpper(entry.getKey().toString()));}System.out.println();}}}
خروجی
Number of instances made = 1
Banana
Number of instances made = 2
Banana
Apple
Number of instances made = 2
Banana
Apple