জাভা স্ট্যাটিক ইনিশিয়ালাইজার্স থ্রেড কি নিরাপদ?


136

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

সাধারণ কোড উদাহরণ হবে;

class FooRegistry {

    static {
        //this code must only ever be called once 
        addController(new FooControllerImpl());
    }

    private static void addController(IFooController controller) { 
        // ...
    }
}

বা আমার এটি করা উচিত;

class FooRegistry {

    static {
        synchronized(FooRegistry.class) {
            addController(new FooControllerImpl());
        }
    }

    private static void addController(IFooController controller) {
        // ...
    }
}

10
আমি এই নকশা পছন্দ করি না, যেহেতু এটি অকেজো। নির্ভরতা ইনজেকশন দেখুন।
ডিএফএ

উত্তর:


199

হ্যাঁ, জাভা স্ট্যাটিক ইনিশিয়ালাইজারগুলি থ্রেড নিরাপদ (আপনার প্রথম বিকল্পটি ব্যবহার করুন)।

যাইহোক, আপনি যদি নিশ্চিত করতে চান যে কোডটি একবারে কার্যকর করা হয়েছে তখন আপনাকে নিশ্চিত করতে হবে যে ক্লাসটি কেবলমাত্র একক শ্রেণি-লোডার দ্বারা লোড করা হয়েছে। স্ট্যাটিক ইনিশিয়েশন একবার ক্লাস-লোডার প্রতি সঞ্চালিত হয়।


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

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

1
হ্যাঁ. স্ট্যাটিক কোড ব্লকটি প্রতিটি শ্রেণি-লোডারকে কল করে যে ক্লাসটি লোড করে।
ম্যাথু মুরডোক

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

1
এর অর্থ কি এই যে 'চূড়ান্ত' কীওয়ার্ডটি হোল্ডারের মধ্যে উদাহরণস্বরূপ হ'ল: en.wikedia.org/wiki/Initialization-on-demand_holder_idiom ?
spc16670

11

এটি এমন একটি কৌশল যা আপনি অলস প্রারম্ভিককরণের জন্য ব্যবহার করতে পারেন

enum Singleton {
    INSTANCE;
}

বা পূর্ব জাভা 5.0 এর জন্য

class Singleton {
   static class SingletonHolder {
      static final Singleton INSTANCE = new Singleton();
   }
   public static Singleton instance() {
      return SingletonHolder.INSTANCE;
   }
}

যেহেতু সিঙ্গলটনহোল্ডারের স্ট্যাটিক ব্লকটি একবারে থ্রেড নিরাপদে চালিত হবে আপনার অন্য কোনও লকিংয়ের দরকার নেই। ক্লাস সিঙ্গলটনহোল্ডার কেবল তখন লোড হবে যখন আপনি দৃষ্টান্তটি কল করবেন ()


18
আপনি এই উত্তরটি ভিত্তিতে স্থির করছেন যে স্থিতিশীল ব্লকটি কেবলমাত্র বিশ্বব্যাপী একবারই কার্যকর করা হবে - যা খুব প্রশ্নই জিজ্ঞাসা করা হয়েছিল।
মাইকেল ময়র্স

2
আমি মনে করি এটিও বহু-শ্রেণীর লোডার পরিবেশে নিরাপদ নয় যা বলে?
আহমাদ

2
@ আহমাদ মাল্টি-ক্লাস লোডার পরিবেশগুলি প্রতিটি অ্যাপ্লিকেশনের নিজস্ব সিলেটলেট থাকতে দেয় সে জন্য ডিজাইন করা হয়েছে।
পিটার লরি

4

সাধারণ পরিস্থিতিতে স্ট্যাটিক ইনিশিয়ালিসারের সবকিছু ঘটে that শ্রেণিটি ব্যবহার করে এমন সমস্ত কিছু আগে, তাই সিঙ্ক্রোনাইজেশন সাধারণত প্রয়োজন হয় না। তবে ক্লাসটি স্ট্যাটিক ইনটিইলাইজার কল করে এমন কোনও কিছুর অ্যাক্সেসযোগ্য (সহ অন্যান্য স্ট্যাটিক ইনিশিয়ালিসারগুলি ডেকে আনা সহ)।

কোনও শ্রেণি লোড হওয়া শ্রেণীর দ্বারা লোড করা যায় তবে সরাসরি তাড়াতাড়ি আরম্ভ করা উচিত নয়। অবশ্যই কোনও শ্রেণি ক্লাস লোডারদের একাধিক উদাহরণ দ্বারা লোড করা যায় এবং এর ফলে একই নামে একাধিক শ্রেণিতে পরিণত হয়।


3

হ্যাঁ, সাজান

একজন staticইনিশিয়ালাইজারকে কেবল একবার ডেকে আনা হয়, সুতরাং সেই সংজ্ঞা অনুসারে এটি থ্রেড নিরাপদ - staticএমনকি থ্রেডের যুক্তি পেতে আপনার কাছে প্রাথমিকের দুটি বা আরও বেশি অনুরোধ প্রয়োজন ।

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

অবশেষে, আপনি যে বিষয়গুলি সিঙ্ক্রোন করছেন তা মনে রাখবেন। আমি বুঝতে পেরেছি এটি আপনি যা জিজ্ঞাসা করছেন তা আসলে নয়, তবে নিশ্চিত হয়ে নিন যে আপনার প্রশ্নটি addController()থ্রেড-নিরাপদ করার দরকার আছে কিনা ।


5
একটি খুব সংজ্ঞায়িত অর্ডার রয়েছে যাতে তাদের বলা হয়: উত্স কোডে আদেশ অনুসারে।
মাফু

এছাড়াও, তারা সর্বদা ডাকা হয়, আপনি তাদের ফলাফলটি ব্যবহার করেন না কেন। জাভা in. এ পরিবর্তিত না হলে
মাফু

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

এটি কুৎসিত হয়, এবং আমি এড়াতে হবে। কিন্তু চক্রগুলি কীভাবে সমাধান করা যায় তার একটি নির্ধারিত উপায় রয়েছে। "জাভা প্রোগ্রামিং ভাষা চতুর্থ সংস্করণ" উদ্ধৃত: পৃষ্ঠা: 75, বিভাগ: 2.5.3 Section স্ট্যাটিক ইনিশিয়ালাইজেশন: "যদি চক্র ঘটে থাকে তবে এক্স এর স্ট্যাটিক ইনিশিয়ালাইজারগুলি কেবলমাত্র সেই স্থানেই কার্যকর করা হবে যেখানে ওয়াইয়ের পদ্ধতিটি চালিত হয়েছিল Y "
জেএমআই ম্যাডিসন

0

হ্যাঁ, স্ট্যাটিক ইনিশিয়ালাইজারগুলি কেবল একবার চালানো হয়। আরও তথ্যের জন্য এটি পড়ুন


2
না, এগুলি একাধিকবার চালানো যেতে পারে।
সীমাবদ্ধ প্রায়শ্চিত্ত

5
না তারা একবার ক্লার্স্লোডার চালানো যাবে।
27

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

-4

সুতরাং মূলত, যেহেতু আপনি একটি সিঙ্গলটন উদাহরণ চান, আপনার এটি কমবেশি পুরানো ধাঁচের পদ্ধতিতে করা উচিত এবং আপনার সিঙ্গলটন অবজেক্টটি একবারে এবং একবার একবার শুরু করা হয়েছে তা নিশ্চিত করা উচিত।

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