লক অবজেক্টটি স্থির থাকতে হবে কেন?


112

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

তবে স্থির কেন?

private static readonly object Locker = new object();

শেষে ক্ষেত্রটি কেবলমাত্র আমার ক্লাসের মধ্যে ব্যবহৃত হয়, এবং আমি কেবল এটির পরিবর্তে এটি ব্যবহার করতে পারি:

private readonly object Locker = new object();

কোন মন্তব্য?

হালনাগাদ:

উদাহরণ হিসাবে আমি এই কোডটি পেস্ট করেছি (কেবল একটি উদাহরণ)। আমি এটিতে স্ট্যাটিক বা নন-স্ট্যাটিক লকার ব্যবহার করতে পারি এবং উভয়ই ভাল কাজ করবে। নীচের উত্তরটি বিবেচনা করে আমার কি বরং আমার লকারটিকে এভাবে সংজ্ঞায়িত করা উচিত? (দুঃখিত আমি পরের সপ্তাহে একটি সাক্ষাত্কার আছে এবং প্রতিটি বিস্তারিত জানা প্রয়োজন :)

private readonly object Locker = new object();

এবং এখানে কোড:

    private int _priceA;
    private int _priceB;
    private EventWaitHandle[] _waithandle;
    private readonly IService _service;

//ctor
public ModuleAViewModel(IService service)
    {
        _service = service;
        _modelA = new ModelA();
        _waithandle = new ManualResetEvent[2];
        _waithandle[0] = new ManualResetEvent(false);
        _waithandle[1] = new ManualResetEvent(false);
        LoadDataByThread();
    }


 private void LoadDataByThread()
        {
            new Thread(() =>
                           {
                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceA = _service.GetPriceA();
                                   }
                                   _waithandle[0].Set();
                               }).Start();

                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceB = _service.GetPriceB();
                                   }
                                   _waithandle[1].Set();
                               }).Start();

                               WaitHandle.WaitAll(_waithandle);
                               PriceA = _priceA;
                               PriceB = _priceB;
                           }).Start();
        }

ধন্যবাদ


15
আমার জ্ঞানের মতে, স্ট্যাটিক সাধারণত এটি উদাহরণস্বরূপ-অজানাস্টিক তৈরি করতে ব্যবহৃত হয়। যদি "মাইওয়ারকারক্লাস" এর বেশ কয়েকটি দৃষ্টান্ত বিদ্যমান থাকে তবে একবারে প্রদত্ত ডেটা দিয়ে কেবল একজনই চালাতে পারবেন (ধরে নিবেন তারা সবাই ভাগ করে নেওয়া সংস্থান ব্যবহার করে)।
ব্র্যাড ক্রিস্টি

2
সম্পাদনায় একটি গুরুত্বপূর্ণ বিশদের অভাব রয়েছে: কোথায় _serviceএবং _waithandleঅবস্থিত? দৃষ্টান্ত? স্ট্যাটিক? অন্যান্য? যে পারে , উদাহরণস্বরূপ, ... একটি দূরবর্তী সার্ভারে ইচ্ছাকৃতভাবে সিঙ্ক্রোনাইজ এক্সেস হতে
মার্ক Gravell

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

উত্তর:


177

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

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

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


24
আপনি কী বিশ্বব্যাপী ডেটা স্থগিত করে লোডিংয়ের আরও ভাল উপায়ে আরও বিশদ দিতে পারেন?
বিজি

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

82

এটি অচল হতে হবে না, আসলে কখনও কখনও এটি স্থির হওয়া উচিত নয়

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

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


28
"এ-হা" এর জন্য +1 ... আপনি একই পরিস্থিতিতে সমস্ত পদ্ধতি লক করবেন, কেবল একই পদ্ধতিতে নয়।
রাডারবাব

3
@ রেডারবব - মাইনর ডিটেইল: আপনি কেবলমাত্র এমন একটি লক নেবেন যাতে আরও ক্লায়েন্ট আগ্রহী হতে পারে এমন সমস্ত পদ্ধতি আপনি লক করবেন না Meth পদ্ধতিগুলি কখনই লক হয় না, এটি কেবল মিটেক্স নেওয়া হয়েছিল।
এর্নো

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

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

28

একটি লকের সুযোগ এবং আজীবন আপনি যে 'জিনিস' লক করতে চান তার উপর নির্ভর করতে পারে / উচিত। স্ট্যাটিক লকগুলি বেশিরভাগ স্থির জিনিসগুলি লক করতে ব্যবহৃত হয়।


3
গৌণ বিশদ: লকটি স্থির নয়, আপনি লকটি সনাক্ত করতে যে জিনিসটি ব্যবহার করেন তা অচল। আর একটি ছোটখাটো বিবরণ: আপনি "জিনিস" লক করবেন না।
গুফা 13

2
হ্যাঁ, আমি মনে করি যদি আমরা ভুল "জিনিসগুলি" লক করার চেষ্টা করি তবে সেগুলি খুব বড় এবং শক্তিশালী হতে পারে এবং একদিন পালাতে পারে।
অধ্যাপক

12
@ গুফা এটি অদ্ভুত, আপনার উপরের একটি মন্তব্যে ঠিক বলেছেন: "আপনি কেবলমাত্র বিষয়গুলিকে অতিমাত্রায় জটিল করে তুলছেন", এখন আমি বলার 1 মিনিট আগে দেখছি, মনে হয় আপনি খুব বেশি জটিল কাজ করেছিলেন :)
নিকোলাস পিটারসেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.