জাভাতে সিঙ্গলটন প্যাটার্ন কার্যকর করার কার্যকর উপায় কী? [বন্ধ]


812

জাভাতে সিঙ্গলটন প্যাটার্ন কার্যকর করার কার্যকর উপায় কী?


1
"জাভাতে একক প্যাটার্ন প্রয়োগের কার্যকর উপায় কী?" দক্ষ নির্ধারণ করুন।
মেরিয়ান প্যাডজিওচ 13

मध्यम . com/@kevalpatel2106/… । এটি সিঙ্গলটন প্যাটার্নে থ্রেড, প্রতিবিম্ব এবং সিরিয়ালাইজেশন সুরক্ষা কীভাবে অর্জন করবেন তার সম্পূর্ণ নিবন্ধ। সিঙ্গেলটন শ্রেণীর সুবিধাগুলি এবং সীমাবদ্ধতাগুলি বোঝার জন্য এটি ভাল উত্স।
কেভাল প্যাটেল

জোশুয়া ব্লচ কার্যকর জাভাতে উল্লেখ করেছেন, এনাম সিঙ্গলটন যাওয়ার সবচেয়ে ভাল উপায়। এখানে আমি বিভিন্ন প্রয়োগগুলি অলস / আগ্রহী ইত্যাদি হিসাবে
শ্রেণীবদ্ধ করেছি

উত্তর:


782

একটি এনাম ব্যবহার করুন:

public enum Foo {
    INSTANCE;
}

জোশুয়া ব্লচ তার কার্যকর জাভা রিলোডেড আলাপে গুগল আই / ও ২০০৮: ভিডিওর লিঙ্কে এই পদ্ধতির ব্যাখ্যা করেছিলেন । এছাড়াও স্লাইড দেখতে তার উপস্থাপনা (এর 30-32 effective_java_reloaded.pdf ):

সিরিয়ালাইজেবল সিঙ্গলটনের প্রয়োগের সঠিক উপায়

public enum Elvis {
    INSTANCE;
    private final String[] favoriteSongs =
        { "Hound Dog", "Heartbreak Hotel" };
    public void printFavorites() {
        System.out.println(Arrays.toString(favoriteSongs));
    }
}

সম্পাদনা: "কার্যকর জাভা" এর একটি অনলাইন অংশ বলেছেন:

"এই পদ্ধতির কার্যক্ষেত্রটি জনসাধারণের ক্ষেত্রের পদ্ধতির সমতুল্য, এটি আরও সংক্ষিপ্ততর ব্যতীত, সিরিয়ালাইজেশন যন্ত্রপাতি বিনামূল্যে সরবরাহ করে এবং পরিশীলিত সিরিয়ালাইজেশন বা প্রতিবিম্বের আক্রমণগুলির মধ্যেও একাধিক তাত্পর্য প্রতিরোধের গ্যারান্টি সরবরাহ করে While যদিও এই পদ্ধতির রয়েছে এখনও বহুলভাবে গ্রহণযোগ্য নয়, একটি একক উপাদানগুলির এনাম প্রকারটি সিঙ্গলটন বাস্তবায়নের সেরা উপায় ""


202
আমি মনে করি লোকেরা এনামগুলিকে বৈশিষ্ট্যযুক্ত একটি শ্রেণি হিসাবে দেখা শুরু করা উচিত। আপনি যদি সংকলন সময়ে আপনার শ্রেণীর উদাহরণগুলি তালিকাভুক্ত করতে পারেন তবে একটি এনাম ব্যবহার করুন।
আমির আরাদ

7
আমি ব্যক্তিগতভাবে প্রায়শই সরাসরি সিঙ্গলটন প্যাটার্নটি ব্যবহার করার প্রয়োজন খুঁজে পাই না। আমি মাঝে মধ্যে একটি অ্যাপ্লিকেশন প্রসঙ্গের সাথে বসন্তের নির্ভরতা ইনজেকশন ব্যবহার করি যা এতে সিঙ্গলেটন হিসাবে বোঝায় contains আমার ইউটিলিটি ক্লাসগুলিতে কেবল স্থিতিশীল পদ্ধতি থাকে এবং এগুলির কোনও দৃষ্টান্তের দরকার নেই।
স্টিফেন ডেন

3
হাই, কেউ কি আমাকে বলতে পারেন কীভাবে পরীক্ষার ক্ষেত্রে এই ধরণের সিঙ্গলটনের উপহাস করা যায় এবং পরীক্ষা করা যায়। আমি এই ধরণের জন্য নকল সিঙ্গলটন উদাহরণ সরিয়ে নেওয়ার চেষ্টা করেছি কিন্তু পারলাম না।
আশীষ শর্মা

29
আমার ধারণা এটি বোধগম্য হয় তবে আমি এখনও এটি পছন্দ করি না। আপনি কীভাবে এমন একটি সিঙ্গলটন তৈরি করবেন যা অন্য শ্রেণি পর্যন্ত প্রসারিত? আপনি যদি এনাম ব্যবহার করেন তবে আপনি পারবেন না।
ছারভে

11
@ বিভিডিবি: আপনি যদি প্রচুর নমনীয়তা চান তবে আপনি ইতিমধ্যে প্রথম স্থানে একটি সিঙ্গলটন প্রয়োগ করে বিচ্যুত হয়ে গেছেন। আপনার যখন প্রয়োজন হয় তখন একটি স্বাধীন উদাহরণ তৈরি করার ক্ষমতা নিজে থেকে অমূল্য।
সিএইচও

233

ব্যবহারের উপর নির্ভর করে বেশ কয়েকটি "সঠিক" উত্তর রয়েছে।

যেহেতু জাভা 5 এটি করার সর্বোত্তম উপায় হ'ল এনুম ব্যবহার করা:

public enum Foo {
   INSTANCE;
}

পূর্ব জাভা ৫, সর্বাধিক সাধারণ কেসটি হ'ল:

public final class Foo {

    private static final Foo INSTANCE = new Foo();

    private Foo() {
        if (INSTANCE != null) {
            throw new IllegalStateException("Already instantiated");
        }
    }

    public static Foo getInstance() {
        return INSTANCE;
    }

    public Object clone() throws CloneNotSupportedException{
        throw new CloneNotSupportedException("Cannot clone instance of this class");
    }
}

কোডটির উপর দিয়ে যাওয়া যাক। প্রথমত, আপনি চান ক্লাসটি চূড়ান্ত হোক। এই ক্ষেত্রে, আমি finalব্যবহারকারীদের এটি চূড়ান্ত জানাতে কীওয়ার্ডটি ব্যবহার করেছি । তারপরে ব্যবহারকারীদের নিজস্ব ফু তৈরি করতে বাধা দেওয়ার জন্য আপনাকে কনস্ট্রাক্টরটিকে ব্যক্তিগত করতে হবে। কনস্ট্রাক্টর থেকে একটি ব্যতিক্রম ছুঁড়ে ফেলা ব্যবহারকারীদের একটি দ্বিতীয় ফু তৈরি করতে প্রতিবিম্ব ব্যবহার করতে বাধা দেয়। তারপরে আপনি private static final Fooএকমাত্র উদাহরণটি ধরে রাখার জন্য একটি ক্ষেত্র এবং public static Foo getInstance()এটিকে ফেরত দেওয়ার জন্য একটি পদ্ধতি তৈরি করেন। জাভা স্পেসিফিকেশন নিশ্চিত করে যে ক্লাসটি প্রথম ব্যবহৃত হবে তখনই কনস্ট্রাক্টরকে ডাকা হবে।

যখন আপনার কাছে খুব বড় কোনও অবজেক্ট বা ভারী নির্মাণ কোড রয়েছে এবং আপনার অন্যান্য অ্যাক্সেসযোগ্য স্থিতিশীল পদ্ধতি বা ক্ষেত্রগুলিও ব্যবহার করতে পারেন যা কোনও উদাহরণ প্রয়োজন হওয়ার আগে, তারপরে এবং কেবল তখনই আপনাকে অলস প্রারম্ভিককরণটি ব্যবহার করতে হবে।

private static classউদাহরণটি লোড করতে আপনি একটি ব্যবহার করতে পারেন । কোডটি এর পরে দেখতে হবে:

public final class Foo {

    private static class FooLoader {
        private static final Foo INSTANCE = new Foo();
    }

    private Foo() {
        if (FooLoader.INSTANCE != null) {
            throw new IllegalStateException("Already instantiated");
        }
    }

    public static Foo getInstance() {
        return FooLoader.INSTANCE;
    }
}

যেহেতু লাইনটি private static final Foo INSTANCE = new Foo();কেবল কার্যকর করা হয় যখন FooLoader ক্লাসটি প্রকৃতপক্ষে ব্যবহৃত হয়, এটি অলস তাত্ক্ষণিকতার যত্ন নেয় এবং এটি থ্রেড নিরাপদে থাকার নিশ্চয়তা দেওয়া হয়।

আপনি যখন নিজের অবজেক্টটি ক্রমিকায়িত করতে সক্ষম হতে চান তখন আপনাকে নিশ্চিত করতে হবে যে ডিসেরায়ালাইজেশন কোনও অনুলিপি তৈরি করবে না।

public final class Foo implements Serializable {

    private static final long serialVersionUID = 1L;

    private static class FooLoader {
        private static final Foo INSTANCE = new Foo();
    }

    private Foo() {
        if (FooLoader.INSTANCE != null) {
            throw new IllegalStateException("Already instantiated");
        }
    }

    public static Foo getInstance() {
        return FooLoader.INSTANCE;
    }

    @SuppressWarnings("unused")
    private Foo readResolve() {
        return FooLoader.INSTANCE;
    }
}

পদ্ধতিটি readResolve()নিশ্চিত করবে যে একমাত্র উদাহরণটি ফিরে আসবে, এমনকি যখন আপনার প্রোগ্রামটির আগের রানটিতে theজেক্টটি সিরিয়ালযুক্ত হয়েছিল।


32
প্রতিবিম্ব জন্য চেক অকেজো। যদি অন্য কোডগুলি বেসরকারীদের প্রতিবিম্ব ব্যবহার করে তবে এটি খেলা শেষ Over এমনকি এই ধরনের অপব্যবহারের অধীনে সঠিকভাবে কাজ করার চেষ্টা করার কোনও কারণ নেই। এবং যদি আপনি চেষ্টা করেন তবে এটি কোনওভাবেই অসম্পূর্ণ "সুরক্ষা" হবে, কেবলমাত্র অনেকগুলি নষ্ট কোড।
ওয়াউটার কোকেয়ার্টস

5
> "প্রথম, আপনি ক্লাসটি চূড়ান্ত হতে চান"। কেউ কি দয়া করে এ সম্পর্কে বিস্তারিত বলতে পারেন?
প্লেগহ্যামার

2
ডিসিরিয়ালাইজেশন সুরক্ষা সম্পূর্ণভাবে ভেঙে গেছে (আমি মনে করি এটি কার্যকর জাভা 2 য় এডে উল্লেখ করা হয়েছে)।
টম হাটিন -

9
-1 এটি একেবারে সর্বাধিক সহজ ঘটনা নয়, এটি সংবিধানযুক্ত এবং অযথা জটিল। আসলে সবচেয়ে সহজ সমাধানের জন্য জোনাথনের উত্তরটি দেখুন যা সমস্ত ক্ষেত্রে 99.9% এ যথেষ্ট।
মাইকেল বর্গওয়ার্ট

2
আপনার সিঙ্গলটনের একটি সুপারক্লাস থেকে উত্তরাধিকার সূত্রে নেওয়া দরকার হলে এটি কার্যকর। আপনি এই ক্ষেত্রে এনাম সিঙ্গলটন প্যাটার্নটি ব্যবহার করতে পারবেন না, যেহেতু এনামগুলির একটি সুপার ক্লাস থাকতে পারে না (যদিও তারা ইন্টারফেস প্রয়োগ করতে পারে)। উদাহরণস্বরূপ, এনাম সিঙ্গেলটন
এতিয়েন নেভু

139

দাবি অস্বীকার: আমি সবে মাত্র দুর্দান্ত উত্তরগুলির সংক্ষিপ্তসার করেছি এবং তা আমার কথায় লিখেছি।


সিঙ্গেলন প্রয়োগ করার সময় আমাদের কাছে দুটি বিকল্প রয়েছে
1. অলস লোডিং
2. প্রারম্ভিক লোডিং

অলস লোডিং বিট ওভারহেড যুক্ত করে (অনেক সত্য বলতে হবে) সুতরাং এটি তখনই ব্যবহার করুন যখন আপনার খুব বড় অবজেক্ট বা ভারী নির্মাণ কোড থাকে এবং অন্যান্য অ্যাক্সেসযোগ্য স্থিতিশীল পদ্ধতি বা ক্ষেত্রগুলিও উদাহরণস্বরূপ প্রয়োজন হওয়ার আগে ব্যবহার করা যেতে পারে এবং কেবল তখনই আপনার অলস সূচনাটি ব্যবহার করা দরকার ther অন্যদিকে তাড়াতাড়ি লোড করা ভাল পছন্দ।

একক বাস্তবায়নের সর্বাধিক সহজ উপায় হ'ল

public class Foo {

    // It will be our sole hero
    private static final Foo INSTANCE = new Foo();

    private Foo() {
        if (INSTANCE != null) {
            // SHOUT
            throw new IllegalStateException("Already instantiated");
        }
    }

    public static Foo getInstance() {
        return INSTANCE;
    }
}

প্রারম্ভিক লোডযুক্ত সিঙ্গলটন বাদে সবকিছুই ভাল। আসুন অলস বোঝা সিঙ্গলটনের চেষ্টা করুন

class Foo {

    // Our now_null_but_going_to_be sole hero 
    private static Foo INSTANCE = null;

    private Foo() {
        if (INSTANCE != null) {
            // SHOUT  
            throw new IllegalStateException("Already instantiated");
        }
    }

    public static Foo getInstance() {
        // Creating only  when required.
        if (INSTANCE == null) {
            INSTANCE = new Foo();
        }
        return INSTANCE;
    }
}

এতক্ষণ ভাল তবে আমাদের নায়ক একাই একাধিক অশুভ থ্রেডের সাথে লড়াই করতে পারবেন না যারা আমাদের নায়কের অনেক উদাহরণ চায়। সুতরাং এটি এটিকে অশুভ মাল্টি থ্রেডিং থেকে রক্ষা দেয়

class Foo {

    private static Foo INSTANCE = null;

    // TODO Add private shouting constructor

    public static Foo getInstance() {
        // No more tension of threads
        synchronized (Foo.class) {
            if (INSTANCE == null) {
                INSTANCE = new Foo();
            }
        }
        return INSTANCE;
    }
}

তবে নায়ককে রক্ষা করার পক্ষে এটি যথেষ্ট নয়, সত্যিই !!! এটি আমাদের নায়ককে সহায়তা করার জন্য সবচেয়ে ভাল / করা উচিত

class Foo {

    // Pay attention to volatile
    private static volatile Foo INSTANCE = null;

    // TODO Add private shouting constructor

    public static Foo getInstance() {
        if (INSTANCE == null) { // Check 1
            synchronized (Foo.class) {
                if (INSTANCE == null) { // Check 2
                    INSTANCE = new Foo();
                }
            }
        }
        return INSTANCE;
    }
}

একে "ডাবল-চেকড লকিং আইডিয়াম" বলা হয়। অস্থির বিবৃতিটি ভুলে যাওয়া সহজ এবং কেন এটি প্রয়োজনীয় তা বোঝা মুশকিল।
বিশদের জন্য: http://www.cs.umd.edu/~pugh/java/mmoryModel/DoubleCheckedLocking.html

এখন আমরা খারাপ থ্রেড সম্পর্কে নিশ্চিত কিন্তু নিষ্ঠুর সিরিয়ালাইজেশন সম্পর্কে কী? ডি-সিরিয়ালিয়েশন করার সময় কোনও নতুন অবজেক্ট তৈরি না হওয়ার পরেও আমাদের তা নিশ্চিত করতে হবে

class Foo implements Serializable {

    private static final long serialVersionUID = 1L;

    private static volatile Foo INSTANCE = null;

    // Rest of the things are same as above

    // No more fear of serialization
    @SuppressWarnings("unused")
    private Object readResolve() {
        return INSTANCE;
    }
}

পদ্ধতিটি readResolve()নিশ্চিত করবে যে একমাত্র উদাহরণটি ফিরে আসবে, এমনকি যখন আমাদের প্রোগ্রামটির আগের রানটিতে বস্তুটি সিরিয়ালযুক্ত হয়েছিল।

অবশেষে আমরা থ্রেড এবং সিরিয়ালাইজেশনের বিরুদ্ধে যথেষ্ট সুরক্ষা যোগ করেছি তবে আমাদের কোডটি ভারী এবং কুশ্রী দেখাচ্ছে। আমাদের নায়ককে একটি মেক আপ দিন

public final class Foo implements Serializable {

    private static final long serialVersionUID = 1L;

    // Wrapped in a inner static class so that loaded only when required
    private static class FooLoader {

        // And no more fear of threads
        private static final Foo INSTANCE = new Foo();
    }

    // TODO add private shouting construcor

    public static Foo getInstance() {
        return FooLoader.INSTANCE;
    }

    // Damn you serialization
    @SuppressWarnings("unused")
    private Foo readResolve() {
        return FooLoader.INSTANCE;
    }
}

হ্যাঁ এটি আমাদের খুব একই নায়ক :)
যেহেতু private static final Foo INSTANCE = new Foo();ক্লাসটি FooLoaderআসলে ব্যবহৃত হয় তখনই লাইনটি কার্যকর করা হয়, এটি অলস তাত্ক্ষণিকতার যত্ন নেয়,

এবং এটি থ্রেড নিরাপদ থাকার গ্যারান্টিযুক্ত।

এবং আমরা এতদূর এসেছি, আমরা যা কিছু করেছি তা অর্জনের সর্বোত্তম উপায় হ'ল সর্বোত্তম উপায়

 public enum Foo {
       INSTANCE;
   }

যা অভ্যন্তরীণভাবে এমন আচরণ করা হবে

public class Foo {

    // It will be our sole hero
    private static final Foo INSTANCE = new Foo();
}

এটাই! সিরিয়ালাইজেশন, থ্রেড এবং কুৎসিত কোডের আর ভয় নেই। এছাড়াও ENUMS সিঙ্গেলটন অলসভাবে শুরু করা হয়েছে

এই পদ্ধতির কার্যক্ষমতা জনসাধারণের ক্ষেত্রের পদ্ধতির সমতুল্য, এটি আরও সংক্ষিপ্ততর ব্যতীত, সিরিয়ালাইজেশন যন্ত্রপাতি বিনামূল্যে সরবরাহ করে এবং পরিশীলিত সিরিয়ালাইজেশন বা প্রতিবিম্বের আক্রমণগুলির মধ্যেও একাধিক তাত্পর্য বিরুদ্ধে আইরনক্ল্যাড গ্যারান্টি সরবরাহ করে। যদিও এই পদ্ধতির এখনও ব্যাপকভাবে গ্রহণ করা সম্ভব হয়নি, তবে একটি একক উপাদান এনাম প্রকারটি সিঙ্গলটন বাস্তবায়নের সর্বোত্তম উপায়।

-জশুয়া ব্লচ "কার্যকর জাভা" তে

এখন আপনি বুঝতে পেরেছেন কেন ENUMS কে সিঙ্গেলটন বাস্তবায়নের সর্বোত্তম উপায় হিসাবে বিবেচনা করা হয় এবং আপনার ধৈর্যের জন্য ধন্যবাদ :)
এটি আমার ব্লগে আপডেট হয়েছে ।


3
কেবল একটি ব্যাখ্যা: এনাম ব্যবহার করে প্রয়োগ করা সিলেটলেটগুলি অলসভাবে শুরু করা হয়। এখানে বিবরণ: stackoverflow.com/questions/16771373/...

2
দুর্দান্ত উত্তর একটি শেষ জিনিস, ব্যতিক্রম ছোঁড়ার ক্লোন পদ্ধতি ওভাররাইড করুন।
ishষিপ 89

2
@ অ্যাক্সিজ সুন্দর ব্যাখ্যা, আমি সত্যিই খুব উপভোগ করেছি এবং খুব সহজেই শিখেছি এবং আমি আশা করি এটি কখনও
ভুলেনি

1
স্ট্যাকওভারফ্লোতে আমি সর্বদা লাল উত্তরগুলির মধ্যে একটি। ধন্যবাদ!
শাই সাদাদোক

1
সেখানে হয় একটি Singleton যেমন enums ব্যবহার করে একটি ধারাবাহিকতাতে সমস্যা: যেকোনো সদস্য ক্ষেত্র মান না ধারাবাহিকভাবে এবং সেইজন্য পুনঃস্থাপিত করা। দেখুন জাভা অবজেক্ট ধারাবাহিকতাতে স্পেসিফিকেশন, সংস্করণ 6.0 । অন্য সমস্যা: কোনও সংস্করণ নেই - সমস্ত এনামের একটি নির্দিষ্ট serialVersionUIDথাকে 0L। তৃতীয় সমস্যা: কোনও কাস্টমাইজেশন নেই: কোনও শ্রেণি-নির্দিষ্ট রাইটওজেক্ট, রিডবজেক্ট, রিডঅবজেক্ট নোডাটা, রাইটরপ্লেস এবং রিড রেজোলিউজ পদ্ধতিগুলি এনাম টাইপের দ্বারা সংজ্ঞায়িত করা সিরিয়ালাইজেশন এবং ডেসারিয়ালাইজেশনের সময় উপেক্ষা করা হয়।
তুলসী বাউর্কের

124

স্টু থম্পসন পোস্ট পোস্টটি জাভা 5.0 এবং তার পরে বৈধ। তবে আমি এটি ব্যবহার না করা পছন্দ করব কারণ আমার ধারণা এটি ত্রুটিযুক্ত pr

অস্থির বিবৃতিটি ভুলে যাওয়া সহজ এবং কেন এটি প্রয়োজনীয় তা বোঝা মুশকিল। অস্থিরতা ছাড়া এই কোডটি ডাবল-চেকড লকিং অ্যান্টিপ্যাটার্নের কারণে আর থ্রেড নিরাপদ হবে না। অনুশীলনে জাভা কনকুরেন্সির অনুচ্ছেদ 16.2.4 এ সম্পর্কে আরও দেখুন । সংক্ষেপে: এই প্যাটার্নটি (জাভা ৫.০ এর পূর্বে বা অস্থির বিবৃতি ব্যতীত) বার অবজেক্টের একটি রেফারেন্স দিতে পারে যা (এখনও) একটি ভুল অবস্থায় রয়েছে state

এই প্যাটার্নটি পারফরম্যান্স অপ্টিমাইজেশনের জন্য উদ্ভাবিত হয়েছিল। তবে এটি সত্যিই আর উদ্বেগ নয়। নিম্নলিখিত অলস সূচনা কোডটি দ্রুত এবং -ও গুরুত্বপূর্ণভাবে পড়া সহজ।

class Bar {
    private static class BarHolder {
        public static Bar bar = new Bar();
    }

    public static Bar getBar() {
        return BarHolder.bar;
    }
}

1
যথেষ্ট ফর্সা! আমি কেবল অস্থির সাথে আরামদায়ক এবং এটির ব্যবহার। ওহ, এবং JCiP এর জন্য তিনটি চিয়ারস।
স্টু থম্পসন

1
ওহ, এটি স্পষ্টতই ফাইন্ডবুগ খ্যাতির উইলিয়াম পুগের পক্ষে মতামত।
স্টু থম্পসন

4
@ এসটিএ কার্যকর জাভার প্রথম সংস্করণ (কপিরাইট 2001) আইটেম 48 এর অধীনে এই
ধরণটির বিশদ জানায়

9
@ বিএনও: কনস্ট্রাক্টরকে বেসরকারী করে তোলার কী আছে?
xyz

2
@ অ্যালিকেলজিন-কিলাকা বেশ নয়। বারহোল্ডারের জন্য শ্রেণি লোডিং পর্বে উদাহরণটি তৈরি করা হয়েছে , এটি প্রথমবারের প্রয়োজন না হওয়া পর্যন্ত বিলম্বিত। বারের কনস্ট্রাক্টর আপনার পছন্দ মতো জটিল হতে পারে তবে এটি প্রথম পর্যন্ত কল করা হবে না getBar()। (এবং যদি getBar"খুব তাড়াতাড়ি" নামে অভিহিত হয় তবে এককভাবে কীভাবে প্রয়োগ করা হয় তা বিবেচনা না করেই আপনি একই সমস্যার মুখোমুখি হবেন।) আপনি উপরের কোডটির অলস ক্লাস লোড দেখতে পাচ্ছেন: পেস্টবিন
ডটকম / আইপি 2eayiR

95

থ্রেড জাভা 5+ এ নিরাপদ:

class Foo {
    private static volatile Bar bar = null;
    public static Bar getBar() {
        if (bar == null) {
            synchronized(Foo.class) {
                if (bar == null)
                    bar = new Bar(); 
            }
        }
        return bar;
    }
}

সম্পাদনা : এখানে সংশোধকটির দিকে মনোযোগ দিন volatile। :) এটি গুরুত্বপূর্ণ কারণ এটি ছাড়া, অন্যান্য থ্রেডের জেএমএম (জাভা মেমোরি মডেল) এর মান পরিবর্তন করে দেখার নিশ্চয়তা দেয় না। সিঙ্ক্রোনাইজেশন এটির যত্ন নেয় না - এটি কেবল কোডের সেই ব্লকের অ্যাক্সেসকে সিরিয়ালাইজ করে।

2 সম্পাদনা করুন : @NNO এর উত্তর বিল পুগ (ফাইন্ডব্যাগস) দ্বারা প্রস্তাবিত পদ্ধতির বিবরণ এবং তর্কযোগ্য আরও ভাল। পড়ুন এবং তার উত্তরও ভোট দিন।


1
অস্থির সংশোধক সম্পর্কে আমি আরও কোথায় জানতে পারি?
এগারোটি 1


2
আমি মনে করি এটি প্রতিফলন আক্রমণ সম্পর্কে উল্লেখ করা গুরুত্বপূর্ণ। সত্য যে বেশিরভাগ বিকাশকারীদের সম্পর্কে উদ্বিগ্ন হওয়ার দরকার নেই, তবে এটি মনে হয় যে এগুলি (এনাম-ভিত্তিক সিঙ্গেলনগুলির চেয়ে বেশি) উদাহরণগুলির মধ্যে এমন কোনও কোড অন্তর্ভুক্ত করা উচিত যা একাধিক-তদন্তের আক্রমণ থেকে রক্ষা করে বা এই জাতীয় সম্ভাবনার ইঙ্গিত দেয় এমন একটি দাবি অস্বীকার করা উচিত।
luis.espinal

2
এখানে ভোল্টাইল কীওয়ার্ডের দরকার নেই - যেমন সিঙ্ক্রোনাইজেশন উভয় পারস্পরিক বর্জন এবং মেমরির দৃশ্যমানতা দেয়।
হেমন্ত

2
জাভা 5+ এ সমস্ত নিয়ে কেন বিরক্ত হন? আমার উপলব্ধি হ'ল এনাম পদ্ধতিটি থ্রেড সুরক্ষা এবং অলস সূচনা উভয়ই সরবরাহ করে। এটিও আরও সহজ ... এছাড়াও, যদি আপনি কোনও এনাম এড়াতে চান তবে আমি নেস্টেড স্ট্যাটিক ক্লাসের পদ্ধতিটি আটকাতে পারি ...
আলেকজান্দ্রোস

91

অলস সূচনা ভুলে যান , এটি খুব সমস্যাযুক্ত। এটি সহজ সমাধান:

public class A {    

    private static final A INSTANCE = new A();

    private A() {}

    public static A getInstance() {
        return INSTANCE;
    }
}

21
সিঙ্গলটন উদাহরণ ভেরিয়েবলও চূড়ান্ত করা যেতে পারে। যেমন, প্রাইভেট স্ট্যাটিক ফাইনাল এ সিঙ্গলটন = নতুন এ ();
jatanp

19
এটি কার্যকরভাবে অলস সূচনা হয়, যেহেতু ক্ল্যাট লোড না হওয়া পর্যন্ত স্ট্যাটিক সিঙ্গলটন তাত্ক্ষণিকভাবে চলবে না এবং প্রয়োজনীয়তা না হওয়া পর্যন্ত ক্লাসটি লোড করা হবে না (যা আপনি প্রথমে getInstance () পদ্ধতিটি উল্লেখ করেছেন এমন সময় সম্পর্কে সঠিক হবে)।
ড্যান ডায়ার

7
স্ট্যাটিকটি তাত্ক্ষণিকভাবে চালিত হওয়ার আগে ক্লাস এ যদি বোঝার উপায়ে আসে, আপনি ক্লাস ইনিশিয়েশনটি ডিকুয়াল করার জন্য স্ট্যাটিকটিকে একটি স্ট্যাটিক ইনার ক্লাসে গুটিয়ে রাখতে পারেন।
টম হাটিন -

3
আমি সম্মত এই উত্তরটি সবচেয়ে সহজ, এবং অনিরুধন, উদাহরণ চূড়ান্ত ঘোষণার দরকার নেই। স্থির সদস্যদের সূচনা করার সময় অন্য কোনও থ্রেড ক্লাসে অ্যাক্সেস পাবে না। এটি কম্পাইলার দ্বারা গ্যারান্টিযুক্ত, অন্য কথায়, সমস্ত স্থির সূচনাটি একটি সিঙ্ক্রোনাইজড পদ্ধতিতে করা হয় - কেবল একটি থ্রেড।
inor

4
এই পদ্ধতির একটি সীমাবদ্ধতা রয়েছে: কনস্ট্রাক্টর একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে না।
wangf

47

আপনার সত্যই এটি প্রয়োজন তা নিশ্চিত করুন। এর বিরুদ্ধে কিছু যুক্তি দেখতে "সিঙ্গেলটন অ্যান্টি-প্যাটার্ন" এর জন্য একটি গুগল করুন। আমি মনে করি এটিতে অন্তর্নিহিত কোনও ভুল নেই তবে আমি মনে করি এটি কিছু বৈশ্বিক উত্স / তথ্য প্রকাশের জন্য কেবল একটি প্রক্রিয়া যাতে নিশ্চিত হয়ে নিন যে এটিই সেরা উপায়। বিশেষত আমি নির্ভরশীলতা ইঞ্জেকশনটি আরও দরকারী বলে খুঁজে পেয়েছি বিশেষত আপনি যদি ইউনিট পরীক্ষাও ব্যবহার করছেন কারণ ডিআই আপনাকে পরীক্ষার উদ্দেশ্যে বিদ্রূপিত সংস্থানগুলি ব্যবহার করতে দেয়।


আপনি প্রচলিত পদ্ধতিতেও মক মানগুলি ইনজেক্ট করতে পারেন তবে আমার ধারণা এটির স্ট্যান্ডার্ড / স্রপিংয়ের উপায় নয় তাই এর অতিরিক্ত কাজটি কেবলমাত্র উত্তরাধিকারের কোড হিসাবে পাওয়া ...
tgkprog

21

আমি সিলেটলেট ব্যবহারের বিকল্প হিসাবে ডিআই-কে প্রস্তাব দেওয়া এমন কয়েকটি জবাব দ্বারা সন্তুষ্ট; এগুলি সম্পর্কযুক্ত ধারণা। আপনি সিঙ্গলটন বা নন-সিঙ্গলটন (যেমন প্রতি থ্রেড) উদাহরণগুলি ইনজেক্ট করতে ডিআই ব্যবহার করতে পারেন। কমপক্ষে এটি সত্য যদি আপনি স্প্রিং ২.x ব্যবহার করেন তবে আমি অন্যান্য ডিআই ফ্রেমওয়ার্কের পক্ষে কথা বলতে পারি না।

সুতরাং ওপিতে আমার উত্তরটি (সবচেয়ে তুচ্ছ নমুনা কোড ব্যতীত সকলের মধ্যে) হতে হবে:

  1. স্প্রিংয়ের মতো একটি ডিআই ফ্রেমওয়ার্ক ব্যবহার করুন
  2. আপনার নির্ভরতাগুলি সিলেটনস, অনুরোধ স্কোপড, সেশন স্কোপড, বা যাই হোক না কেন এটি আপনার ডিআই কনফিগারেশনের অংশ করুন।

এই পদ্ধতির সাহায্যে আপনাকে একটি দুর্দান্ত ডিকপলড (এবং সেইজন্য নমনীয় এবং পরীক্ষামূলক) আর্কিটেকচার দেওয়া হয় যেখানে সিঙ্গলটন ব্যবহার করা উচিত তা সহজেই প্রত্যাবর্তনযোগ্য বাস্তবায়ন বিশদ (আপনি যে কোনও সিঙ্গলটনের ব্যবহার করেন থ্রেডসেফ অবশ্যই প্রদান করুন)।


4
সম্ভবত লোকেরা আপনার সাথে একমত নয়। আমি আপনাকে অগ্রাহ্য করি নি, তবে আমি একমত নই: আমি মনে করি সিআইলেটনের মতো ডিআই একই সমস্যাগুলি সমাধান করতে ব্যবহার করা যেতে পারে। এটি "সিঙ্গেলটন" বোঝার উপর ভিত্তি করে "একটি একক উদাহরণ সহ একটি বস্তু যা সরাসরি বিশ্বব্যাপী নাম দ্বারা অ্যাক্সেস করা হয়" এর পরিবর্তে কেবল "একক উদাহরণের সাথে একটি বস্তু" নয় যা সম্ভবত কিছুটা কৌশলযুক্ত।
টম অ্যান্ডারসন

2
এই সামান্য প্রসারিত করতে, TicketNumbererএকটি একক বিশ্বব্যাপী দৃষ্টান্ত প্রয়োজন যা বিবেচনা করুন , এবং যেখানে আপনি একটি ক্লাস লিখতে চান যেখানে TicketIssuerকোডের একটি লাইন রয়েছে int ticketNumber = ticketNumberer.nextTicketNumber();। Traditionalতিহ্যবাহী সিঙ্গলটন চিন্তাভাবনায়, আগের কোডের লাইনটি এমন কিছু হতে হবে TicketNumberer ticketNumberer = TicketNumberer.INSTANCE;। ডিআই ভাবাতে, ক্লাসের মতো কনস্ট্রাক্টর থাকত public TicketIssuer(TicketNumberer ticketNumberer) { this.ticketNumberer = ticketNumberer; }
টম অ্যান্ডারসন

2
এবং সেই কনস্ট্রাক্টরকে কল করা অন্য কারও সমস্যা হয়ে দাঁড়িয়েছে। একটি ডিআই ফ্রেমওয়ার্ক এটি কোনও ধরণের বিশ্বব্যাপী মানচিত্র দিয়ে করবে; একটি হ্যান্ডবিল্ট ডিআই আর্কিটেকচার এটি করবে কারণ অ্যাপ্লিকেশনটির mainপদ্ধতি (বা এর কোনও মাইনইস) নির্ভরতা তৈরি করবে এবং তারপরে কনস্ট্রাক্টরকে কল করবে। মূলত, গ্লোবাল ভেরিয়েবল (বা একটি বৈশ্বিক পদ্ধতি) এর ব্যবহার হ'ল ভয়ঙ্কর পরিষেবা লোকেটার প্যাটার্নের কেবল একটি সহজ রূপ , এবং সেই প্যাটার্নের অন্যান্য ব্যবহারের মতো নির্ভরতা ইনজেকশন দ্বারা প্রতিস্থাপন করা যেতে পারে।
টম অ্যান্ডারসন

@ টমএন্ডারসন লোকেরা কেন পরিষেবা লোকেটারের ধরণকে 'ভয়' দেয় তা সম্পর্কে আমি সত্যিই বিভ্রান্ত। আমি মনে করি বেশিরভাগ ক্ষেত্রে এটি অত্যধিক দক্ষ হয় বা সর্বোপরি প্রয়োজন হয় না তবে, আপাতদৃষ্টিতে দরকারী ক্ষেত্রে রয়েছে। কম সংখ্যক প্যারামের সাথে ডিআই অবশ্যই স্পষ্টভাবে পছন্দ করা হয় তবে 20+ এর কল্পনা করুন। কোডটি কাঠামোগত নয় এমনটি বৈধ যুক্তি নয়, কারণ কখনও কখনও পরামিতিগুলির গোষ্ঠীকরণের অর্থ হয় না। এছাড়াও, একক পরীক্ষার দৃষ্টিকোণ থেকে, আমি পরিষেবাটি, এটির কেবলমাত্র ব্যবসায়িক যুক্তি পরীক্ষা করার বিষয়ে চিন্তা করি না এবং যদি এটি ঠিক কোড করে দেওয়া হয় তবে এটি সহজ হবে। আমি কেবল খুব বড় আকারের প্রকল্পগুলিতে এই প্রয়োজনটি দেখেছি।
ব্র্যান্ডন লিং

20

সত্যই বিবেচনা করুন কেন এটি লেখার আগে আপনার একটি সিঙ্গলটন প্রয়োজন। এগুলি ব্যবহারের জন্য একটি দ্বি-ধর্মীয় বিতর্ক রয়েছে যা আপনি জাভাতে সিঙ্গেলন গুগল করলে আপনি সহজেই হোঁচট খেতে পারেন।

ব্যক্তিগতভাবে আমি বহু কারণে যতবার সম্ভব সিলেটলেটগুলি এড়াতে চেষ্টা করি, এর মধ্যে বেশিরভাগ বেশিরভাগই গুগলিং সিঙ্গেলটনের মাধ্যমে পাওয়া যেতে পারে। আমি মনে করি যে প্রায়শই সিঙ্গেলনগুলি অপব্যবহার করা হয় কারণ তারা প্রত্যেকে সহজেই বুঝতে পারে, তারা ওও ডিজাইনে "গ্লোবাল" ডেটা পাওয়ার জন্য একটি প্রক্রিয়া হিসাবে ব্যবহৃত হয় এবং সেগুলি ব্যবহার করা হয় কারণ অবজেক্ট লাইফাইসাইকেল পরিচালনা (অথবা আপনি কীভাবে খ এর ভিতর থেকে A করতে পারেন তা নিয়ে ভাবছেন)। একটি দুর্দান্ত মিডগ্রাউন্ডের জন্য ইনভার্শন অফ কন্ট্রোল (আইওসি) বা ডিপেন্ডেন্সি ইনজেকশন (ডিআই) এর মতো জিনিসগুলি দেখুন।

আপনার যদি সত্যই প্রয়োজন হয় তবে উইকিপিডিয়ায় একটি সিঙ্গলটনের যথাযথ প্রয়োগের একটি ভাল উদাহরণ রয়েছে।


একমত। এটি এমন একটি ফাউন্ডেশনাল ক্লাসের বেশি যা আপনার বাকী অ্যাপ্লিকেশনটিকে কিক-শুরু করে এবং যদি এটি সদৃশ হয়ে থাকে তবে আপনি একটি সম্পূর্ণ বিশৃঙ্খলা (অর্থাৎ কোনও সংস্থার একক অ্যাক্সেস বা সুরক্ষা কার্যকর করা) শেষ করবেন। আপনার সমস্ত অ্যাপ্লিকেশন জুড়ে গ্লোবাল ডেটা পাস করা একটি বড় কাপলিং লাল পতাকা। আপনার সত্যিকারের প্রয়োজনের স্বীকৃতি পেলে এটি ব্যবহার করুন।
সালভাদোর ভ্যালেন্সিয়া

16

নিম্নলিখিত 3 পৃথক পদ্ধতির হয়

1) এনুম

/**
* Singleton pattern example using Java Enumj
*/
public enum EasySingleton{
    INSTANCE;
}

2) ডাবল চেকড লকিং / অলস লোডিং

/**
* Singleton pattern example with Double checked Locking
*/
public class DoubleCheckedLockingSingleton{
     private static volatile DoubleCheckedLockingSingleton INSTANCE;

     private DoubleCheckedLockingSingleton(){}

     public static DoubleCheckedLockingSingleton getInstance(){
         if(INSTANCE == null){
            synchronized(DoubleCheckedLockingSingleton.class){
                //double checking Singleton instance
                if(INSTANCE == null){
                    INSTANCE = new DoubleCheckedLockingSingleton();
                }
            }
         }
         return INSTANCE;
     }
}

3) স্ট্যাটিক কারখানা পদ্ধতি

/**
* Singleton pattern example with static factory method
*/

public class Singleton{
    //initailzed during class loading
    private static final Singleton INSTANCE = new Singleton();

    //to prevent creating another instance of Singleton
    private Singleton(){}

    public static Singleton getSingleton(){
        return INSTANCE;
    }
}

13

আমি আমার সিলেটলেটগুলি পরিচালনা করতে স্প্রিং ফ্রেমওয়ার্ক ব্যবহার করি। এটি শ্রেণীর "সিঙ্গেলন-নেস" প্রয়োগ করে না (একাধিক শ্রেণীর লোডার জড়িত থাকলে আপনি যা সত্যিই করতে পারেন না) তবে বিভিন্ন ধরণের অবজেক্ট তৈরির জন্য বিভিন্ন কারখানাগুলি তৈরি এবং কনফিগার করার সত্যিই সহজ উপায় সরবরাহ করে।


11

উইকিপিডিয়ায় জাভাতেও সিঙ্গলেটনের কয়েকটি উদাহরণ রয়েছে। জাভা 5 বাস্তবায়ন দেখতে বেশ সম্পূর্ণ দেখাচ্ছে এবং এটি থ্রেড-নিরাপদ (ডাবল-চেকড লক প্রয়োগ করা হয়েছে)।


11

সংস্করণ 1:

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

অলস লোডিং, ব্লকিংয়ের সাথে থ্রেড নিরাপদ, এর কারণে কম পারফরম্যান্স synchronized

সংস্করণ 2:

public class MySingleton {
    private MySingleton() {}
    private static class MySingletonHolder {
        public final static MySingleton instance = new MySingleton();
    }
    public static MySingleton getInstance() {
        return MySingletonHolder.instance;
    }
}

অলস লোডিং, নন-ব্লকিং, উচ্চ কার্যকারিতা সহ নিরাপদ থ্রেড।


10

আপনার যদি অলস লোডিংয়ের প্রয়োজন না হয় তবে কেবল চেষ্টা করুন

public class Singleton {
    private final static Singleton INSTANCE = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() { return Singleton.INSTANCE; }

    protected Object clone() {
        throw new CloneNotSupportedException();
    }
}

আপনি যদি অলস লোডিং চান এবং আপনি চান যে আপনার সিঙ্গলটন থ্রেড-নিরাপদ হোক, ডাবল-চেকিং প্যাটার্নটি চেষ্টা করুন

public class Singleton {
        private static Singleton instance = null;

        private Singleton() {}

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

        protected Object clone() {
            throw new CloneNotSupportedException();
        }
}

যেহেতু ডাবল চেকিং প্যাটার্নটি কাজ করার গ্যারান্টিযুক্ত নয় (সংকলকগুলির সাথে কিছু সমস্যার কারণে, আমি সে সম্পর্কে আরও কিছু জানি না)), আপনি সম্পূর্ণ getInstance- পদ্ধতিটি সিঙ্ক্রোনাইজ করতে বা আপনার সমস্ত সিলেটলেটের জন্য একটি রেজিস্ট্রি তৈরি করতে চেষ্টা করতে পারেন।


2
প্রথম সংস্করণটি সেরা। ক্লাসটি সিঙ্গলটন সরবরাহ করা ব্যতীত অন্য কিছু করেন না বলে ধরে নেওয়া, অলস শ্রেণির লোডিংয়ের কারণে এটি সাধারণত দ্বিতীয় সংস্করণটির মতো একই পয়েন্টে ইনস্ট্যান্ট করা হবে।
ড্যান ডায়ার

1
স্থির জন্য ডাবল-চেকিং অর্থহীন। এবং আপনি সুরক্ষিত ক্লোন পদ্ধতিটি কেন সর্বজনীন করেছেন?
টম হাটিন -

1
-1 আপনার ডাবল চেকড লকিংয়ের সংস্করণটি ভেঙে গেছে।
Assylias 8'12

5
এছাড়াও আপনাকে আপনার volatile
সিঙ্গলটনকে

প্রথম সংস্করণ হয় অলস এবং থ্রেড-নিরাপদ।
মিহা_এক্স 64

9

আমি বলব এনাম সিঙ্গলটন

জাভাতে এনাম ব্যবহার করে সিঙ্গেলটন সাধারণত এনাম সিঙ্গলটন ঘোষণার উপায়। এনাম সিঙ্গলটনে উদাহরণ পরিবর্তনশীল এবং উদাহরণ পদ্ধতি থাকতে পারে। সরলতার স্বার্থে, এও নোট করুন যে আপনি যদি সেই পদ্ধতির থ্রেড সুরক্ষা নিশ্চিত করার প্রয়োজনের চেয়ে কোনও উদাহরণ পদ্ধতি ব্যবহার করেন তবে তা যদি কোনওভাবে অবজেক্টের অবস্থাকে প্রভাবিত করে।

এনামের ব্যবহার কার্যকর করা খুব সহজ এবং সিরিয়ালাইজযোগ্য অবজেক্টগুলির বিষয়ে কোনও ত্রুটি নেই, যা অন্যান্য উপায়ে ছড়িয়ে দিতে হয়।

/**
* Singleton pattern example using Java Enum
*/
public enum Singleton {
        INSTANCE;
        public void execute (String arg) {
                //perform operation here
        }
}

আপনি এটি অ্যাক্সেস করতে পারেন Singleton.INSTANCE, getInstance()সিঙ্গলটনে কল করার পদ্ধতির চেয়ে অনেক সহজ ।

1.12 এনাম কনস্ট্যান্টগুলির সিরিয়ালকরণ ization

এনাম ধ্রুবকগুলি সাধারণ সিরিয়ালাইজযোগ্য বা বহিরাগতযোগ্য বস্তুর চেয়ে আলাদাভাবে সিরিয়ালযুক্ত হয়। এনাম ধ্রুবকের ক্রমিক রূপটি সম্পূর্ণরূপে এর নাম নিয়ে থাকে; ধ্রুবকের ক্ষেত্রের মানগুলি ফর্মটিতে উপস্থিত নেই। একটি এনাম ধ্রুবককে ক্রমিকায়িত করতে ObjectOutputStreamএনাম ধ্রুবকের নাম পদ্ধতি দ্বারা ফেরত মানটি লিখুন। একটি এনাম ধ্রুবককে deserialize করতে, ObjectInputStreamস্ট্রিম থেকে ধ্রুবক নামটি পড়ে; ডিসরিয়ালাইজড ধ্রুবকটি পরে java.lang.Enum.valueOfপদ্ধতিটি কল করে ধ্রুবকের এনাম টাইপটি আর্গুমেন্ট হিসাবে প্রাপ্ত ধ্রুবক নামটি দিয়ে পাস করা হয়। অন্যান্য সিরিয়ালাইজযোগ্য বা বহির্গমনযোগ্য বস্তুর মতো, এনাম ধ্রুবকগুলি পরবর্তীকালে সিরিয়ালাইজেশন স্ট্রিমের পিছনে উল্লেখের লক্ষ্য হিসাবে কাজ করতে পারে।

প্রক্রিয়া যার মাধ্যমে enum ধ্রুবক ধারাবাহিকভাবে হয় কাস্টমাইজড করা যাবে না: কোনো বর্গ-নির্দিষ্ট writeObject, readObject, readObjectNoData, writeReplace, এবং readResolveপদ্ধতি enum ধরনের দ্বারা সংজ্ঞায়িত ধারাবাহিকতাতে এবং deserialization সময় উপেক্ষা করা হয়। একইভাবে, যে কোনও serialPersistentFieldsবা serialVersionUIDক্ষেত্রের ঘোষণাগুলিও উপেক্ষা করা হয় - সমস্ত এনাম ধরণের একটি নির্দিষ্ট serialVersionUIDথাকে 0L। এনাম প্রকারের জন্য সিরিয়ালযোগ্য ক্ষেত্র এবং ডেটা নথিভুক্ত করা অপ্রয়োজনীয়, যেহেতু প্রেরিত ডেটার ধরণের কোনও প্রকারভেদ নেই।

ওরাকল ডক্স থেকে উদ্ধৃত

প্রচলিত সিঙ্গলটনের সাথে আর একটি সমস্যা হ'ল একবার আপনি Serializableইন্টারফেস প্রয়োগ করার পরে সেগুলি আর সিঙ্গেলটন থেকে যায় না কারণ readObject()পদ্ধতিটি সর্বদা জাভাতে কনস্ট্রাক্টরের মতো একটি নতুন উদাহরণ দেয়। readResolve()নীচের মত সিঙ্গলটন দিয়ে প্রতিস্থাপন করে নতুন তৈরি করা দৃষ্টান্তটি ব্যবহার করে এবং বাতিল করে এড়ানো যায়

 // readResolve to prevent another instance of Singleton
 private Object readResolve(){
     return INSTANCE;
 }

আপনার সিঙ্গলটন ক্লাসটি রাষ্ট্রের বজায় রাখলে এটি আরও জটিল হয়ে উঠতে পারে, যেমন আপনি এগুলিকে ক্ষণস্থায়ী করে তোলা দরকার তবে এনাম সিঙ্গলটনে জেভিএম দ্বারা সিরিয়ালাইজেশন নিশ্চিত করা হয়েছে।


ভাল পড়ুন

  1. একক প্যাটার্ন
  2. এনামস, সিঙ্গলেটন এবং ডিসরিয়ালাইজেশন
  3. ডাবল-চেকড লকিং এবং সিঙ্গলটন প্যাটার্ন

8
There are 4 ways to create a singleton in java.

1- eager initialization singleton

    public class Test{
        private static final Test test = new Test();
        private Test(){}
        public static Test getTest(){
            return test;
        }
    

2- lazy initialization singleton (thread safe)

    public class Test {
         private static volatile Test test;
         private Test(){}
         public static Test getTest() {
            if(test == null) {
                synchronized(Test.class) {
                    if(test == null){test = new Test();
                }
            }
         }

        return test;
    


3- Bill Pugh Singleton with Holder Pattern (Preferably the best one)

    public class Test {

        private Test(){}

        private static class TestHolder{
            private static final Test test = new Test();
        }

        public static Test getInstance(){
            return TestHolder.test;
        }
    }

4- enum singleton
      public enum MySingleton {
        INSTANCE;
    private MySingleton() {
        System.out.println("Here");
    }
}

(1) আগ্রহী নয়, এটি জেভিএম বর্গ লোডিং পদ্ধতির কারণে অলস।
মিহা_এক্স 64

@ মিহা_এক্স 64৪ যখন আমি উত্সাহী লোডিংয়ের কথা বললাম, আমি আগ্রহী সূচনা বললাম u আপনি যদি উভয়ই সমান হন তবে আগ্রহী লোডিং কী। আপনি যদি কোনও বই লিখেন এবং জোশুয়া ব্লচের মতো আগের লেখকদের দ্বারা করা ভুলগুলি সংশোধন করা উচিত।
ধীররাজ সচান

কার্যকর জাভা একটি দুর্দান্ত বই, তবে অবশ্যই সম্পাদনা দরকার।
মিহা_এক্স 64

@ মিহা_এক্স ৪ কী উত্সাহী লোড হচ্ছে, আপনি উদাহরণ দিয়ে ব্যাখ্যা করতে পারেন
ধীররাজ সত্যান

'অধীর আগ্রহে' কিছু করার অর্থ 'যত তাড়াতাড়ি সম্ভব'। উদাহরণস্বরূপ, হাইবারনেট স্পষ্টভাবে প্রয়োজন হলে, লোডিং সম্পর্কগুলিকে অধীর আগ্রহে সমর্থন করে।
মিহা_এক্স 64

8

এটিতে খেলায় কিছুটা দেরি হতে পারে তবে একটি সিঙ্গলটন বাস্তবায়নের আশেপাশে প্রচুর উপদ্রব রয়েছে। ধারক প্যাটার্নটি অনেক পরিস্থিতিতে ব্যবহার করা যায় না। অস্থির ব্যবহার করার সময় এবং আইএমও - আপনার একটি স্থানীয় ভেরিয়েবল ব্যবহার করা উচিত। শুরুতে শুরু করুন এবং সমস্যার উপর পুনরাবৃত্তি করা যাক। আপনি যা বলতে চাইছেন তা আপনি দেখতে পাবেন।


প্রথম প্রচেষ্টাটি এরকম কিছু দেখতে পাবে:

public class MySingleton {

     private static MySingleton INSTANCE;

     public static MySingleton getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new MySingleton();
        }

        return INSTANCE;
    }
    ...
}

এখানে আমাদের মাইসিংলেটন ক্লাস রয়েছে যার একটি বেসরকারী স্ট্যাটিক সদস্য রয়েছে যার নাম ইনস্ট্যান্সেনসি, এবং পাবলিক স্ট্যাটিক পদ্ধতি যা গেটইন্সট্যান্স () বলে। প্রথমবার getInstance () বলা হয়, ইনস্ট্যান্টের সদস্যটি শূন্য। প্রবাহটি তারপরে সৃষ্টি অবস্থায় পড়বে এবং মাইসিংটন ক্লাসের একটি নতুন উদাহরণ তৈরি করবে। GetInstance () -এর পরবর্তী কলগুলি দেখতে পাবে যে ইনস্ট্যান্স ভেরিয়েবলটি ইতিমধ্যে সেট করা আছে, এবং অন্য কোনও মাইসিংলেটনের উদাহরণ তৈরি করে না। এটি নিশ্চিত করে যে মাইসিংলেটনের কেবলমাত্র একটি উদাহরণ রয়েছে যা getInstance () এর সমস্ত কলকারীদের মধ্যে ভাগ করা আছে।

তবে এই বাস্তবায়নে সমস্যা আছে। একক দৃষ্টান্ত তৈরির জন্য মাল্টি-থ্রেডযুক্ত অ্যাপ্লিকেশনগুলির একটি রেসের শর্ত থাকবে। যদি মৃত্যুর একাধিক থ্রেড একই সময়ে (বা তার আশেপাশে) getInstance () পদ্ধতিতে আঘাত করে, তারা প্রত্যেকে ইনস্ট্যান্সের সদস্যকে শূন্য হিসাবে দেখবে। এর ফলে প্রতিটি থ্রেড একটি নতুন মাইসিংলেটন ইনস্ট্যান্স তৈরি করবে এবং পরবর্তীকালে ইনস্ট্যান্টের সদস্য নির্ধারণ করবে।


private static MySingleton INSTANCE;

public static synchronized MySingleton getInstance() {
    if (INSTANCE == null) {
        INSTANCE = new MySingleton();
    }

    return INSTANCE;
}

এখানে আমরা getInstance () পদ্ধতিটি সিঙ্ক্রোনাইজ করতে পদ্ধতি স্বাক্ষরে সিঙ্ক্রোনাইজড কীওয়ার্ডটি ব্যবহার করেছি। এটি অবশ্যই আমাদের জাতির অবস্থা ঠিক করবে। থ্রেডগুলি এখন একবারে একবারে পদ্ধতিটি প্রবেশ করে প্রবেশ করবে। তবে এটি একটি পারফরম্যান্স সমস্যা তৈরি করে। এই প্রয়োগটি কেবলমাত্র একক দৃষ্টান্ত তৈরির ক্ষেত্রে সিঙ্ক্রোনাইজ করে না, এটি রিড সহ সমস্ত কলকে getInstance () এ সিঙ্ক্রোনাইজ করে। পাঠাগুলি সিঙ্ক্রোনাইজ করার দরকার নেই কারণ তারা কেবল ইনস্ট্যান্সের মান দেয়। যেহেতু পাঠাগুলি আমাদের কলগুলির সিংহভাগ তৈরি করবে (মনে রাখবেন, ইনস্ট্যান্টেশন কেবলমাত্র প্রথম কলেই ঘটে), তাই পুরো পদ্ধতিটি সিঙ্ক্রোনাইজ করে আমরা একটি অপ্রয়োজনীয় পারফরম্যান্স হ'ব।


private static MySingleton INSTANCE;

public static MySingleton getInstance() {
    if (INSTANCE == null) {
        synchronize(MySingleton.class) {
            INSTANCE = new MySingleton();
        }
    }

    return INSTANCE;
}

এখানে আমরা পদ্ধতির স্বাক্ষর থেকে একটি সিঙ্ক্রোনাইজড ব্লকে সিঙ্ক্রোনাইজেশন স্থানান্তরিত করেছি যা মাইসিংলেটনের উদাহরণটি তৈরি করে। কিন্তু এটি কি আমাদের সমস্যার সমাধান করে? ঠিক আছে, আমরা আর পড়তে বাধা দিচ্ছি না, তবে আমরা পিছনেও একটি পদক্ষেপ নিয়েছি। একাধিক থ্রেড একই সময়ে বা তার কাছাকাছি getInstance () পদ্ধতিতে আঘাত করবে এবং তারা সকলেই ইনস্ট্যান্সের সদস্যকে শূন্য হিসাবে দেখবে। তারপরে তারা সিঙ্ক্রোনাইজড ব্লকে আঘাত করবে যেখানে কোনওটি লকটি গ্রহণ করবে এবং উদাহরণটি তৈরি করবে। যখন সেই থ্রেডটি ব্লক থেকে প্রস্থান করে, অন্যান্য থ্রেডগুলি লকের পক্ষে লড়াই করবে এবং প্রতিটি থ্রেড একে একে ব্লকের মধ্যে পড়ে আমাদের শ্রেণীর একটি নতুন উদাহরণ তৈরি করবে। সুতরাং আমরা ঠিক যেখানে ফিরে এসেছি।


private static MySingleton INSTANCE;

public static MySingleton getInstance() {
    if (INSTANCE == null) {
        synchronized(MySingleton.class) {
            if (INSTANCE == null) {
                INSTANCE = createInstance();
            }
        }
    }

    return INSTANCE;
}

এখানে আমরা ব্লকটি ভিতরে রেখে আরও একটি চেক জারি করি। যদি ইনস্ট্যান্সের সদস্যটি ইতিমধ্যে সেট করা থাকে তবে আমরা সূচনাটি এড়িয়ে যাব। একে ডাবল-চেকড লকিং বলা হয়।

এটি আমাদের একাধিক তাত্ক্ষণিক সমস্যার সমাধান করে। তবে আরও একবার, আমাদের সমাধান আরও একটি চ্যালেঞ্জ উপস্থাপন করেছে। অন্যান্য থ্রেডগুলি হয়ত "দেখতে" পাবে না যে ইনস্ট্যান্সের সদস্য আপডেট হয়েছে। এটি জাভা কীভাবে মেমরি অপারেশনগুলিকে অনুকূল করে তোলে। থ্রেডগুলি মূল মেমরি থেকে ভেরিয়েবলের মূল মানগুলি সিপিইউয়ের ক্যাশে অনুলিপি করে। মানগুলিতে পরিবর্তনগুলি তখন সেই ক্যাশে লিখিত হয় এবং পড়ে থাকে read এটি জাভাটির একটি বৈশিষ্ট্য যা পারফরম্যান্স অনুকূল করতে তৈরি করা হয়েছে। তবে এটি আমাদের সিঙ্গলটন বাস্তবায়নের জন্য সমস্যা তৈরি করে। একটি দ্বিতীয় থ্রেড - একটি আলাদা সিপিইউ বা কোর দ্বারা প্রক্রিয়াজাত করা হচ্ছে, একটি পৃথক ক্যাশে ব্যবহার করে - প্রথমটি করা পরিবর্তনগুলি দেখতে পাবে না। এটি দ্বিতীয় থ্রেডটিকে ইনস্টলস সদস্যটিকে নকল হিসাবে দেখতে পাবে যা আমাদের সিঙ্গলটনের একটি নতুন উদাহরণ তৈরি করতে বাধ্য করছে।


private static volatile MySingleton INSTANCE;

public static MySingleton getInstance() {
    if (INSTANCE == null) {
        synchronized(MySingleton.class) {
            if (INSTANCE == null) {
                INSTANCE = createInstance();
            }
        }
    }

    return INSTANCE;
}

আমরা এটি ইনস্ট্যান্সের সদস্য ঘোষণার ক্ষেত্রে অস্থির কীওয়ার্ড ব্যবহার করে সমাধান করি। এটি সংকলককে সর্বদা প্রধান মেমরি থেকে পড়তে এবং লিখতে বলবে, এবং সিপিইউ ক্যাশে নয়।

তবে এই সাধারণ পরিবর্তনটি ব্যয় করে আসে। যেহেতু আমরা সিপিইউ ক্যাশেকে বাইপাস করছি, আমরা প্রতিবার অস্থির ইনস্ট্যান্স সদস্যের উপর পরিচালিত হলে একটি পারফরম্যান্স হিট করব - যা আমরা 4 বার করি। আমরা অস্তিত্বকে ডাবল-চেক করি (1 এবং 2), মান (3) নির্ধারণ করি এবং তারপরে মানটি (4) ফিরিয়ে আনি। যে কেউ তর্ক করতে পারে যে এই পথটি হ'ল ফ্রিঞ্জ কেস কারণ আমরা কেবল পদ্ধতির প্রথম কল করার সময় উদাহরণটি তৈরি করি। সম্ভবত সৃষ্টিতে আঘাত করা একটি পারফরম্যান্স সহনীয়। এমনকি আমাদের মূল ব্যবহারের ক্ষেত্রেও পড়েন, অস্থির সদস্যের উপর দু'বার কাজ করবে। একবার অস্তিত্ব যাচাই করার জন্য, এবং তার মানটি ফেরত দিতে।


private static volatile MySingleton INSTANCE;

public static MySingleton getInstance() {
    MySingleton result = INSTANCE;
    if (result == null) {
        synchronized(MySingleton.class) {
            result = INSTANCE;
            if (result == null) {
                INSTANCE = result = createInstance();
            }
        }
    }

    return result;
}

যেহেতু পারফরম্যান্স হিটটি অস্থির সদস্যের সরাসরি অপারেটিংয়ের কারণে, তাই আসুন অস্থিরতার মানের জন্য একটি স্থানীয় ভেরিয়েবল সেট করি এবং পরিবর্তে স্থানীয় ভেরিয়েবলটিতে কাজ করি। এটি আমাদের অস্থির উপর চালিয়ে যাওয়ার সংখ্যা হ্রাস পাবে এবং এর ফলে আমাদের হারিয়ে যাওয়া কিছু পারফরম্যান্স দাবি করে। মনে রাখবেন যে আমরা যখন সিঙ্ক্রোনাইজড ব্লকে প্রবেশ করি তখন আমাদের স্থানীয় ভেরিয়েবলটি আবার সেট করতে হবে। এটি নিশ্চিত করে যে আমরা লকটির জন্য অপেক্ষা করতে থাকাকালীন যে কোনও পরিবর্তন ঘটেছিল তা আপডেট রয়েছে।

আমি সম্প্রতি এই সম্পর্কে একটি নিবন্ধ লিখেছিলাম। দ্য সিঙ্গলটন ডেকনস্ট্রাকচারিং । আপনি এই উদাহরণগুলিতে আরও তথ্যের এবং সেখানে "ধারক" প্যাটার্নের উদাহরণ খুঁজে পেতে পারেন। ডাবল-চেকড অস্থির পদ্ধতির প্রদর্শন করে এমন একটি বাস্তব-জগতের উদাহরণও রয়েছে। আশাকরি এটা সাহায্য করবে.


আপনি দয়া করে ব্যাখ্যা করতে পারেন কেন BearerToken instanceআপনার নিবন্ধে না static? এবং এটা কি result.hasExpired()?
ওয়াল্যান্ড

এবং কি class MySingleton- সম্ভবত এটি করা উচিত final?
ওোল্যান্ড

1
@ ওয়াল্যান্ড BearerTokenউদাহরণটি স্থির নয় কারণ এটি এর অংশ BearerTokenFactory - যা একটি নির্দিষ্ট অনুমোদন সার্ভারের সাথে কনফিগার করা হয়েছে। অনেকগুলি BearerTokenFactoryঅবজেক্ট থাকতে পারে - প্রত্যেকের নিজস্ব নিজস্ব "ক্যাশেড" রয়েছে BearerTokenযা এটির মেয়াদ শেষ না হওয়া অবধি এটি আউট হয়ে যায়। hasExpired()উপর পদ্ধতি BeraerTokenকারখানা এর বলা হয় get()পদ্ধতি নিশ্চিত করার এটা ঠিক মতো করতে না একটি টোকেনটি মেয়াদউত্তীর্ণ হয়েছে। যদি মেয়াদ উত্তীর্ণ হয় তবে একটি নতুন টোকেনের অনুমোদন সার্ভারের অনুরোধ করা হবে। কোড ব্লকের নিম্নলিখিত অনুচ্ছেদে এটি আরও বিশদে ব্যাখ্যা করে।
মাইকেল অ্যান্ড্রুজ

4

এটি একটি সহজ বাস্তবায়ন কিভাবে singleton:

public class Singleton {
    // It must be static and final to prevent later modification
    private static final Singleton INSTANCE = new Singleton();
    /** The constructor must be private to prevent external instantiation */ 
    private Singleton(){}
    /** The public static method allowing to get the instance */
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

এইভাবে সঠিকভাবে অলস করতে কিভাবে আপনার singleton:

public class Singleton {
    // The constructor must be private to prevent external instantiation   
    private Singleton(){}
    /** The public static method allowing to get the instance */
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
    /** 
     * The static inner class responsible for creating your instance only on demand,
     * because the static fields of a class are only initialized when the class
     * is explicitly called and a class initialization is synchronized such that only 
     * one thread can perform it, this rule is also applicable to inner static class
     * So here INSTANCE will be created only when SingletonHolder.INSTANCE 
     * will be called
     */
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
}

দু'জনই অলস, একমাত্র সিঙ্গলটন থেকে আপনার প্রয়োজনীয় জিনিসটি অনুমান করা এটির উদাহরণ।
মিহা_এক্স 64

@ মিহা_এক্স 64৪ জেভিএম ক্লাস শুরু করার সময় প্রথম কেসটি সিঙ্গেলটন ইনস্ট্যান্ট করবে, দ্বিতীয় ফোন করার সময় কেবল সিঙ্গেলটনকে তাত্পর্যপূর্ণ করবে getInstance() । তবে প্রকৃতপক্ষে যদি আপনার ক্লাসে অন্য কোনও স্থিতিশীল পদ্ধতি না থাকে Singletonএবং আপনি কেবল কল getInstance()করেন তবে কোনও বাস্তব পার্থক্য নেই।
নিকোলাস ফিলোটো

3

আপনার যদি ক্লাসের উদাহরণ ভেরিয়েবলটি অলসভাবে লোড করতে হয় তবে আপনার ডাবল-চেকিং আইডিয়াম প্রয়োজন। আপনার যদি কোনও স্ট্যাটিক ভেরিয়েবল বা একটি সিঙ্গলটন অলসভাবে লোড করতে হয় তবে আপনার চাহিদা হোল্ডার আইডিয়োমের উদ্যোগ নেওয়া দরকার ।

এছাড়াও, যদি সিঙ্গেলটনকে সিরিলাইজ করার প্রয়োজন হয়, তবে সিঙ্গলটন অবজেক্ট ইনগ্রেন্টটি বজায় রাখার জন্য অন্যান্য সমস্ত ক্ষেত্রের ক্ষণস্থায়ী এবং রিড রিসলভ () পদ্ধতিটি প্রয়োগ করা দরকার। অন্যথায়, প্রতিবার অবজেক্টটি ডিসিরিয়ালাইজ করা হলে, অবজেক্টের একটি নতুন উদাহরণ তৈরি করা হবে। রিডরসলভ () যা করে তা হ'ল রিডবজেক্ট () দ্বারা পঠিত নতুন বস্তুর প্রতিস্থাপন, যা সেই নতুন অবজেক্টটিকে আবর্জনা সংগ্রহ করতে বাধ্য করেছিল কারণ সেখানে কোনও পরিবর্তনশীল উল্লেখ নেই ring

public static final INSTANCE == ....
private Object readResolve() {
  return INSTANCE; // original singleton instance.
} 

3

সিঙ্গলটন অবজেক্ট তৈরির বিভিন্ন উপায়:

  1. জোশুয়া ব্লচ অনুসারে - এনাম সেরা হবে।

  2. আপনি ডাবল চেক লকিং ব্যবহার করতে পারেন।

  3. এমনকি অভ্যন্তরীণ স্ট্যাটিক বর্গ ব্যবহার করা যেতে পারে।


3

এনাম সিঙ্গলটন

থ্রেড-সেফ একটি সিঙ্গেলটন কার্যকর করার সহজ উপায় হ'ল এনুম ব্যবহার করা

public enum SingletonEnum {
  INSTANCE;
  public void doSomething(){
    System.out.println("This is a singleton");
  }
}

এই কোডটি জাভা 1.5 তে এনামের প্রবর্তনের পর থেকে কাজ করে

ডাবল চেক লক করা

আপনি যদি একটি "ক্লাসিক" সিঙ্গলটন কোড করতে চান যা বহুবিবাহিত পরিবেশে কাজ করে (জাভা 1.5 থেকে শুরু করে) আপনার এটি ব্যবহার করা উচিত।

public class Singleton {

  private static volatile Singleton instance = null;

  private Singleton() {
  }

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

এটি 1.5 এর আগে থ্রেড-নিরাপদ নয় কারণ উদ্বায়ী কীওয়ার্ডের প্রয়োগটি ভিন্ন ছিল।

প্রারম্ভিক লোডিং সিঙ্গলটন (জাভা 1.5 এর আগেও কাজ করে)

ক্লাসটি লোড হয়ে গেলে এবং থ্রেড সুরক্ষা সরবরাহ করে যখন এই বাস্তবায়নটি সিঙ্গেলটন তাত্ক্ষণিক করে।

public class Singleton {

  private static final Singleton instance = new Singleton();

  private Singleton() {
  }

  public static Singleton getInstance() {
    return instance;
  }

  public void doSomething(){
    System.out.println("This is a singleton");
  }

}

2

জেএসই 5.0 এবং তদূর্ধ্বের জন্য এনাম পদ্ধতিটি গ্রহণ করুন, অন্যথায় স্ট্যাটিক সিঙ্গলটন ধারক পদ্ধতির ব্যবহার করুন ((বিল পুগের দ্বারা বর্ণিত একটি অলস লোডিং পদ্ধতির) ল্যাটার সলিউশনটি বিশেষ ভাষা নির্মানের প্রয়োজন ছাড়াই থ্রেড-নিরাপদও রয়েছে (যেমন উদ্বায়ী বা সংহত))।


2

সিঙ্গেলটনের বিরুদ্ধে প্রায়শই ব্যবহৃত অন্য যুক্তি হ'ল তাদের পরীক্ষারযোগ্যতা সমস্যা। সিলেটলেটগুলি পরীক্ষার উদ্দেশ্যে সহজেই উপহাসযোগ্য হয় না। যদি এটি কোনও সমস্যা হিসাবে দেখা দেয় তবে আমি নিম্নলিখিতটি সামান্য পরিবর্তন করতে চাই:

public class SingletonImpl {

    private static SingletonImpl instance;

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

    public static void setInstance(SingletonImpl impl) {
        instance = impl;
    }

    public void a() {
        System.out.println("Default Method");
    }
}

যুক্ত setInstanceপদ্ধতিটি পরীক্ষার সময় সিঙ্গলটন ক্লাসের একটি মকআপ বাস্তবায়ন সেট করতে দেয়:

public class SingletonMock extends SingletonImpl {

    @Override
    public void a() {
        System.out.println("Mock Method");
    }

}

এটি প্রাথমিক সূচনা পদ্ধতির সাথেও কাজ করে:

public class SingletonImpl {

    private static final SingletonImpl instance = new SingletonImpl();

    private static SingletonImpl alt;

    public static void setInstance(SingletonImpl inst) {
        alt = inst;
    }

    public static SingletonImpl getInstance() {
        if (alt != null) {
            return alt;
        }
        return instance;
    }

    public void a() {
        System.out.println("Default Method");
    }
}

public class SingletonMock extends SingletonImpl {

    @Override
    public void a() {
        System.out.println("Mock Method");
    }

}

এটিরও সাধারণ প্রয়োগে এই কার্যকারিতাটি প্রকাশ করার ত্রুটি রয়েছে। এই কোডটিতে কাজ করা অন্যান্য বিকাশকারীদের নির্দিষ্ট ফাংশন পরিবর্তন করতে এবং এইভাবে পুরো প্রয়োগের আচরণটি পরিবর্তন করতে ´setInstance´ পদ্ধতিটি ব্যবহার করার প্রলোভন দেখাতে পারে, সুতরাং এই পদ্ধতিটি জাভাদোকটিতে কমপক্ষে একটি ভাল সতর্কতা থাকা উচিত।

তবুও, মকআপ-টেস্টিংয়ের সম্ভাবনার জন্য (যখন প্রয়োজন হবে), এই কোড এক্সপোজারটি প্রদানের জন্য একটি গ্রহণযোগ্য মূল্য হতে পারে।


1

সিম্পল সিঙ্গলটন ক্লাস

public class Singleton {
  private static Singleton singleInstance = new Singleton();
  private Singleton() {}
  public static Singleton getSingleInstance() {
    return singleInstance;
  }
}

1
এটি নীচে
জোনাথনের

1
সদৃশ এই সহোদর উত্তর দ্বারা জনাথন পাঁচ বছর আগে পোস্ট করা হয়েছে। আকর্ষণীয় মন্তব্যের জন্য উত্তরটি দেখুন।
বাসিল বাউর্ক

0

আমি এখনও জাভা 1.5 এর পরেও মনে করি, এনাম হ'ল সহজলভ্য সিঙ্গলটন বাস্তবায়ন যা এটি একাধিক থ্রেডযুক্ত পরিবেশেও নিশ্চিত করে - কেবলমাত্র একটি উদাহরণ তৈরি করা হয়েছে।

public enum Singleton{ INSTANCE; }

এবং আপনি সম্পন্ন !!!


1
এটি ইতিমধ্যে বহু বছর আগে অন্যান্য উত্তরে উল্লেখ করা হয়েছে।
পাং

0

এই পোস্টে একবার দেখুন।

জাভা কোর লাইব্রেরিতে GoF ডিজাইন প্যাটার্নগুলির উদাহরণ

সেরা উত্তরের "সিঙ্গেলটন" বিভাগ থেকে,

সিঙ্গেলটন (ক্রিয়েটিভ পদ্ধতি দ্বারা একই সময়ে ফিরে আসা (সাধারণত নিজেরাই) প্রত্যক্ষযোগ্য)

  • java.lang.Runtime # getRuntime ()
  • java.awt.Desktop # getDesktop ()
  • java.lang.System # getSecurityManager ()

আপনি নিজেরাই জাভা নেটিভ ক্লাস থেকে সিঙ্গলটনের উদাহরণ শিখতে পারেন।


0

আমি যে সেরা সিঙ্গলটন প্যাটার্নটি দেখেছি সেগুলি সরবরাহকারী ইন্টারফেসটি ব্যবহার করে।

  • এটি জেনেরিক এবং পুনরায় ব্যবহারযোগ্য
  • এটি অলস সূচনা সমর্থন করে
  • এটি সূচনা না হওয়া পর্যন্ত এটি কেবল সিঙ্ক্রোনাইজ করা হয়, তারপরে ব্লকিং সরবরাহকারীকে একটি অ-ব্লক সরবরাহকারী সরবরাহ করা হয়।

নিচে দেখ:

public class Singleton<T> implements Supplier<T> {

    private boolean initialized;
    private Supplier<T> singletonSupplier;

    public Singleton(T singletonValue) {
        this.singletonSupplier = () -> singletonValue;
    }

    public Singleton(Supplier<T> supplier) {
        this.singletonSupplier = () -> {
            // The initial supplier is temporary; it will be replaced after initialization
            synchronized (supplier) {
                if (!initialized) {
                    T singletonValue = supplier.get();
                    // Now that the singleton value has been initialized,
                    // replace the blocking supplier with a non-blocking supplier
                    singletonSupplier = () -> singletonValue;
                    initialized = true;
                }
                return singletonSupplier.get();
            }
        };
    }

    @Override
    public T get() {
        return singletonSupplier.get();
    }
}

-3

কখনও কখনও একটি সাধারণ " static Foo foo = new Foo();" যথেষ্ট নয়। আপনি যে কিছু বেসিক ডেটা সন্নিবেশ করতে চান তা কেবল ভাবেন।

অন্যদিকে আপনাকে এমন কোনও পদ্ধতি সিঙ্ক্রোনাইজ করতে হবে যা সিঙ্গলটন ভেরিয়েবলকে তত্ক্ষণিত করে। সিঙ্ক্রোনাইজেশন যেমন খারাপ হয় না তবে এটি কার্য সম্পাদন সমস্যা বা লক করতে পারে (উদাহরণটি ব্যবহার করে খুব বিরল পরিস্থিতিতে। সমাধানটি হ'ল)

public class Singleton {

    private static Singleton instance = null;

    static {
          instance = new Singleton();
          // do some of your instantiation stuff here
    }

    private Singleton() {
          if(instance!=null) {
                  throw new ErrorYouWant("Singleton double-instantiation, should never happen!");
          }
    }

    public static getSingleton() {
          return instance;
    }

}

এখন কি হয়? ক্লাসটি ক্লাস লোডার মাধ্যমে লোড করা হয়। বাইট অ্যারে থেকে ক্লাসটি ব্যাখ্যা করার পরে, ভিএম স্ট্যাটিক block } ব্লক কার্যকর করে। এটি পুরো গোপনীয়তা: স্থির-ব্লকটি কেবল একবার ডাকা হয়, যে সময় প্রদত্ত প্যাকেজের প্রদত্ত শ্রেণি (নাম) এই এক শ্রেণির লোডার দ্বারা লোড করা হয়।


3
সত্য না. ক্লাস লোড হওয়ার সাথে সাথে স্ট্যাটিক ভেরিয়েবলগুলি স্ট্যাটিক ব্লকের পাশাপাশি শুরু করা হয়। ঘোষণাটি বিভক্ত করার দরকার নেই।
ক্রেগ পি। মোটলিন

-5
public class Singleton {

    private static final Singleton INSTANCE = new Singleton();

    private Singleton(){
    if (INSTANCE != null)
        throw new IllegalStateException (“Already instantiated...”);
}

    public synchronized static Singleton getInstance() { 
    return INSTANCE;

    }

}

যেহেতু আমরা getInstance এর আগে সিঙ্ক্রোনাইজড কীওয়ার্ডটি যুক্ত করেছি, আমরা যখন দুটি থ্রেড একই সাথে getInstance বলি তখন ক্ষেত্রে রেসের শর্তটি এড়িয়ে চলেছি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.