0Pricing
Java Academy · درس

Singleton: تطبيقات آمنة للخيوط

أنشئ Singleton آمنًا للخيوط باستخدام القفل مزدوج التحقق أو enum أو نمط holder

Singleton: تطبيقات آمنة للخيوط درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

نمط Singleton

يضمن Singleton وجود نسخة واحدة فقط من الفئة في JVM. ومن حالات استخدامه الشائعة: مدراء الإعدادات، ومجمّعات الاتصالات، وخدمات التسجيل.

Singleton ساذج — غير آمن للخيوط

يفشل Singleton الكسول التقليدي عند الوصول المتزامن؛ إذ يمكن لخيطين أن يتجاوزا التحقق من null في الوقت نفسه، وينشئا نسختين.

public class Config {
    private static Config instance;
    private Config() {}
    public static Config getInstance() {
        if (instance == null) {              // race condition!
            instance = new Config();
        }
        return instance;
    }
}

دالة متزامنة — بسيطة لكنها بطيئة

تؤدي إضافة synchronized إلى getInstance() إلى جعلها آمنة للخيوط، لكنها تفرض قفلًا في كل استدعاء، حتى بعد إنشاء النسخة، مما يسبب كلفة زائدة غير ضرورية.

public static synchronized Config getInstance() {
    if (instance == null) instance = new Config();
    return instance;
}

القفل مع التحقق المزدوج

تحققوا من دون قفل، ثم تحققوا مرة أخرى داخل كتلة synchronized. ويتطلب ذلك استخدام volatile للحقل لمنع إعادة ترتيب التعليمات.

public class Config {
    private static volatile Config instance;
    private Config() {}
    public static Config getInstance() {
        if (instance == null) {
            synchronized (Config.class) {
                if (instance == null) instance = new Config();
            }
        }
        return instance;
    }
}

الحامل للتهيئة عند الطلب

هذا هو Singleton الكسول الأكثر أمانًا وكفاءة: تحتفظ فئة داخلية ثابتة وخاصة بالنسخة. ولا تحمّل JVM هذه الفئة إلا عند استدعاء getInstance() للمرة الأولى؛ فتحميل الفئات آمن للخيوط بطبيعته.

public class Config {
    private Config() {}
    private static final class Holder {
        static final Config INSTANCE = new Config();
    }
    public static Config getInstance() {
        return Holder.INSTANCE;
    }
}

Singleton باستخدام enum

توصي Effective Java باستخدام enum يحتوي على ثابت واحد. فهذا الأسلوب موجز وآمن للخيوط وآمن عند التسلسل، كما أنه محصّن ضد هجمات الانعكاس.

public enum AppConfig {
    INSTANCE;
    private String apiUrl = "https://api.example.com";
    public String getApiUrl() { return apiUrl; }
}
// Usage:
String url = AppConfig.INSTANCE.getApiUrl();

التهيئة المبكرة

إذا كانت كلفة بدء التشغيل مقبولة، فابدؤوا تهيئة النسخة عند تحميل الفئة باستخدام حقل static final. هذا الأسلوب بسيط وآمن للخيوط، لكنه ينشئ النسخة دائمًا حتى إن لم تُستخدم مطلقًا.

public class Config {
    private static final Config INSTANCE = new Config();
    private Config() {}
    public static Config getInstance() { return INSTANCE; }
}

Singleton والتسلسل

ينتج عن تسلسل Singleton ثم إلغاء تسلسله نسخة جديدة، ما لم تضيفوا readResolve() التي تعيد INSTANCE. أما أسلوب enum فيتعامل مع ذلك تلقائيًا.

private Object readResolve() { return INSTANCE; }

Singleton وهجمات الانعكاس

يمكن للانعكاس استدعاء المُنشئات الخاصة. واجهوا ذلك بطرح استثناء من المُنشئ إذا كانت هناك نسخة موجودة مسبقًا. أما Singleton باستخدام enum فهو محصّن وفقًا لمواصفات JVM.

private Config() {
    if (Holder.INSTANCE != null) {
        throw new IllegalStateException("Use getInstance()");
    }
}

Singleton في أطر حقن الاعتماديات

في Spring، تكون الحبوب Singleton افتراضيًا (@Scope("singleton")). ونادرًا ما تحتاجون إلى تطبيق نمط Singleton يدويًا؛ اتركوا حاوية DI تديره.

@Component  // Spring manages a single instance
public class FeatureFlags {
    private final boolean darkMode = true;
    public boolean isDarkMode() { return darkMode; }
}

اختبار كائنات Singleton

يصعب اختبار كائنات Singleton اختبارًا وحداتيًا لأنها تحمل حالة عامة. فضّلوا حقن الاعتماديات على شيفرة Singleton اليدوية، وحقنوا نسخًا وهمية في الاختبارات عبر الحقن باستخدام المُنشئ.

اختبار سريع

ما نهج Singleton الذي توصي به Effective Java؟

مراجعة

بالنسبة إلى Singleton الآمن للخيوط، استخدموا الحامل للتهيئة عند الطلب أو أسلوب enum. وتجنّبوا التهيئة الكسولة الساذجة. وفي تطبيقات Spring، اتركوا للإطار إدارة النطاق.

الأسئلة الشائعة

هل درس «Singleton: تطبيقات آمنة للخيوط» مجاني؟

نعم — نص درس «Singleton: تطبيقات آمنة للخيوط» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «Singleton: تطبيقات آمنة للخيوط»؟

أنشئ Singleton آمنًا للخيوط باستخدام القفل مزدوج التحقق أو enum أو نمط holder تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «Singleton: تطبيقات آمنة للخيوط»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. Singleton: تطبيقات آمنة للخيوط
  2. نمط Factory Method
  3. Abstract Factory لعائلات المنتجات
  4. نمط Builder مع Fluent API
← العودة إلى Java Academy