আমি volatile
কীওয়ার্ড সম্পর্কে কিছু নিবন্ধ পড়েছিলাম তবে আমি এর সঠিক ব্যবহারটি বের করতে পারিনি। এটি দয়া করে আমাকে বলতে পারেন যে এটি সি # এবং জাভাতে কী ব্যবহার করা উচিত?
আমি volatile
কীওয়ার্ড সম্পর্কে কিছু নিবন্ধ পড়েছিলাম তবে আমি এর সঠিক ব্যবহারটি বের করতে পারিনি। এটি দয়া করে আমাকে বলতে পারেন যে এটি সি # এবং জাভাতে কী ব্যবহার করা উচিত?
উত্তর:
সি # এবং জাভা উভয়ের জন্যই "অস্থির" সংকলকটিকে বলে যে একটি ভেরিয়েবলের মান কখনই ক্যাশে করা উচিত না কারণ এর মান প্রোগ্রামের আওতার বাইরে পরিবর্তন হতে পারে। সংকলকটি এমন কোনও অপ্টিমাইজেশন এড়িয়ে যাবে যা ভেরিয়েবলটি "তার নিয়ন্ত্রণের বাইরে" পরিবর্তন করে তবে সমস্যার কারণ হতে পারে।
এই উদাহরণ বিবেচনা করুন:
int i = 5;
System.out.println(i);
সংকলকটি এইটিকে কেবল 5 টি মুদ্রণের জন্য এটি অনুকূল করতে পারে:
System.out.println(5);
যাইহোক, যদি অন্য থ্রেড থাকে যা পরিবর্তন করতে পারে i
তবে এটিই ভুল আচরণ। যদি অন্য থ্রেডটি i
6 এ পরিবর্তিত হয় তবে অনুকূলিত সংস্করণটি এখনও 5 মুদ্রণ করবে।
volatile
শব্দ যেমন অপ্টিমাইজেশান এবং ক্যাশে বাধা দেয়, এবং এইভাবে দরকারী যখন একটি পরিবর্তনশীল অন্য থ্রেড দ্বারা পরিবর্তন করা যাবে।
i
হিসাবে চিহ্নিত volatile
। জাভাতে এটি সম্পর্কের আগে ঘটে যাওয়া সমস্ত বিষয় ।
i
স্থানীয় পরিবর্তনশীল হয় তবে অন্য কোনও থ্রেড এটিকে যাইহোক পরিবর্তন করতে পারে না। যদি এটি কোনও ক্ষেত্র হয় তবে সংকলক কলটি অপ্টিমাইজ করতে পারে না যতক্ষণ না final
। আমি মনে করি না যে সংকলকটি ক্ষেত্রটিকে "দেখায়" final
যখন এটি স্পষ্টভাবে ঘোষণা করা হয় না তখন ধরে নেওয়া যায় তার ভিত্তিতে অনুকূলকরণ করতে পারে ations
কোনও চলককে অস্থির কী করে তা বোঝার জন্য, ভেরিয়েবলটি অস্থির না হলে কী ঘটে তা বোঝা গুরুত্বপূর্ণ।
যখন দুটি থ্রেড এ এবং বি একটি অ-উদ্বায়ী ভেরিয়েবল অ্যাক্সেস করছে তখন প্রতিটি থ্রেড তার স্থানীয় ক্যাশে ভেরিয়েবলের স্থানীয় অনুলিপি বজায় রাখবে। এটির স্থানীয় ক্যাশে থ্রেড এ দ্বারা করা কোনও পরিবর্তন থ্রেড বি তে দৃশ্যমান হবে না A
যখন ভেরিয়েবলগুলি অস্থির হিসাবে ঘোষিত হয় তখন এর মূল অর্থ হ'ল থ্রেডগুলিতে এই জাতীয় পরিবর্তনশীলটিকে ক্যাশে করা উচিত নয় বা অন্য কথায় থ্রেডগুলি এই ভেরিয়েবলগুলির মানগুলিকে বিশ্বাস করা উচিত নয় যতক্ষণ না তারা সরাসরি মূল স্মৃতি থেকে না পড়ে।
সুতরাং, যখন একটি পরিবর্তনশীল অস্থির করতে?
যখন আপনার কোনও ভেরিয়েবল থাকে যা অনেকগুলি থ্রেড দ্বারা অ্যাক্সেস করা যায় এবং আপনি প্রতিটি থ্রেডটি সেই চলকের সর্বশেষ আপডেট হওয়া মানটি পেতে চান যদিও মানটি প্রোগ্রামের বাইরের কোনও থ্রেড / প্রক্রিয়া / বাইরের দ্বারা আপডেট করা হয়।
অস্থির ক্ষেত্রগুলির পাঠগুলি শব্দার্থবিজ্ঞান অর্জন করেছে । এর অর্থ এই যে গ্যারান্টিযুক্ত যে নীচের যে কোনও স্মৃতি পড়ার আগে উদ্বায়ী ভেরিয়েবল থেকে পড়া মেমরিটি ঘটবে। এটি সংকলকটিকে পুনঃক্রম করতে বাধা দেয় এবং হার্ডওয়্যারটির যদি এটির প্রয়োজন হয় (দুর্বলভাবে আদেশ করা সিপিইউ), এটি একটি বিশেষ নির্দেশ ব্যবহার করবে হার্ডওয়্যারটিকে অস্থির পড়ার পরে ঘটে এমন কোনও রিড যা অনুমানমূলকভাবে শুরু করা হয়েছিল তা শুরু করার জন্য, বা সিপিইউ পারে লোড অর্জন এবং এর অবসর গ্রহণের ইস্যুটির মধ্যে কোনও অনুমানমূলক লোড যাতে না ঘটে সেজন্য প্রথম দিকে তাদের জারি করা থেকে বিরত রাখুন।
অস্থির ক্ষেত্রগুলির লেখাগুলি শব্দার্থবিজ্ঞানের প্রকাশ করেছে । এর অর্থ এই যে গ্যারান্টিযুক্ত যে কোনও স্মৃতি অস্থায়ী পরিবর্তনশীলকে লিখবে তার পূর্ববর্তী সমস্ত মেমরির লেখাগুলি অন্যান্য প্রসেসরের কাছে দৃশ্যমান না হওয়া পর্যন্ত বিলম্ব হওয়ার গ্যারান্টিযুক্ত।
নিম্নলিখিত উদাহরণ বিবেচনা করুন:
something.foo = new Thing();
যদি foo
কোনও শ্রেণিতে সদস্যের পরিবর্তনশীল হয় এবং অন্যান্য সিপিইউগুলির দ্বারা উল্লিখিত অবজেক্টের অ্যাক্সেস থাকে তবে something
তারা নির্ধারকটিতে স্মৃতি লেখার আগে বিশ্বব্যাপী দৃশ্যমান হওয়ার আগে মান foo
পরিবর্তন দেখতে পারে ! "দুর্বলভাবে অর্ডার করা মেমরি" এর অর্থ এটি। এটি সংঘটিত হতে পারে এমনকি যদি সংকলকটির কাছে কনস্ট্রাক্টরের সমস্ত স্টোর দোকান আগে থাকে । যদি থাকে তবে স্টোরটি প্রকাশের শব্দার্থক হবে এবং হার্ডওয়্যারটি গ্যারান্টি দেয় যে লেখার আগে লেখার আগে সমস্ত লেখক অন্য প্রসেসরের কাছে দৃশ্যমান হওয়ার আগে লেখার অনুমতি দেয় ।Thing
foo
foo
volatile
foo
foo
foo
লেখকদের foo
এত খারাপভাবে পুনরায় সাজানো কীভাবে সম্ভব ? যদি ক্যাশে লাইন হোল্ডিং foo
ক্যাশে থাকে এবং কনস্ট্রাক্টরের স্টোরগুলি ক্যাশে মিস করে, তবে ক্যাশের কাছে লেখাগুলি মিস করার চেয়ে লেখার চেয়ে স্টোরের পক্ষে খুব দ্রুত সম্পন্ন করা সম্ভব।
ইন্টেলের কাছ থেকে (ভয়াবহ) ইটানিয়াম আর্কিটেকচার মেমরির দুর্বলতার অর্ডার করেছিল। মূল এক্সবক্স 360 এ ব্যবহৃত প্রসেসরটি মেমরির দুর্বলভাবে অর্ডার করেছিল। খুব জনপ্রিয় এআরএমভি 7-এ সহ অনেকগুলি এআরএম প্রসেসর দুর্বলভাবে মেমরির আদেশ দিয়েছে।
বিকাশকারীরা প্রায়শই এই ডেটা দৌড়গুলি দেখতে পান না কারণ লকগুলির মতো জিনিসগুলি একটি সম্পূর্ণ স্মৃতি বাধা তৈরি করবে, মূলত একই সময়ে শব্দার্থবিদ্যা অর্জন এবং প্রকাশের মতো একই জিনিস। লকটি অর্জিত হওয়ার আগে লকের অভ্যন্তরে কোনও বোঝা অনুমানমূলকভাবে কার্যকর করা যায় না, লকটি অর্জিত না হওয়া পর্যন্ত তারা বিলম্বিত হয়। কোনও স্টোর কোনও লক রিলিজ জুড়ে বিলম্বিত হতে পারে না, তালাবন্ধির ভিতরে করা সমস্ত লেখাই বিশ্বব্যাপী দৃশ্যমান না হওয়া পর্যন্ত লকটি প্রকাশিত নির্দেশাবলী বিলম্বিত হয়।
আরও একটি সম্পূর্ণ উদাহরণ হ'ল "ডাবল-চেকড লকিং" প্যাটার্ন। এই প্যাটার্নটির উদ্দেশ্য হ'ল কোনও বস্তুকে অলস করার জন্য সর্বদা একটি লক অর্জন করা এড়ানো।
উইকিপিডিয়া থেকে ছিনিয়ে নেওয়া:
public class MySingleton {
private static object myLock = new object();
private static volatile MySingleton mySingleton = null;
private MySingleton() {
}
public static MySingleton GetInstance() {
if (mySingleton == null) { // 1st check
lock (myLock) {
if (mySingleton == null) { // 2nd (double) check
mySingleton = new MySingleton();
// Write-release semantics are implicitly handled by marking
// mySingleton with 'volatile', which inserts the necessary memory
// barriers between the constructor call and the write to mySingleton.
// The barriers created by the lock are not sufficient because
// the object is made visible before the lock is released.
}
}
}
// The barriers created by the lock are not sufficient because not all threads
// will acquire the lock. A fence for read-acquire semantics is needed between
// the test of mySingleton (above) and the use of its contents. This fence
// is automatically inserted because mySingleton is marked as 'volatile'.
return mySingleton;
}
}
এই উদাহরণে, MySingleton
কনস্ট্রাক্টর স্টোরগুলি অন্য প্রসেসরের কাছে স্টোর থেকে যাওয়ার আগে দৃশ্যমান নাও হতে পারে mySingleton
। যদি এটি হয়, অন্য থ্রেডগুলি যে মাইসিংটনে উঁকি দিয়েছে তা কোনও লক অর্জন করবে না এবং তারা প্রয়োজনীয়ভাবে নির্মাণকারীর কাছে লেখাগুলি তুলবে না।
volatile
কখনও ক্যাচিং প্রতিরোধ করে না এটি যা করে তা হ'ল গ্যারান্টি হ'ল অন্য প্রসেসরগুলি "দেখুন" লিখেছেন। সমস্ত বিচারাধীন লেখাগুলি শেষ না হওয়া পর্যন্ত একটি স্টোর রিলিজ একটি স্টোরকে বিলম্বিত করে এবং একটি প্রসেসর প্রসেসর প্রাসঙ্গিক লাইনগুলি ক্যাশেড হওয়ার পরে তাদের ক্যাশে লাইনটি বাতিল / লিখনব্যাক করতে বলছে cycle একটি লোড অর্জন যে কোনও অনুমানকৃত পাঠকে ফ্লাশ করবে, তা নিশ্চিত করে যে তারা অতীত থেকে বাসি মান হবে না।
head
এবং উভয়ই tail
উদ্বিগ্ন tail
হওয়া দরকার এবং গ্রাহককে ধরে head
নিবে না যে পরিবর্তন হবে না। এছাড়াও, head
স্টোরটি বিশ্বব্যাপী দৃশ্যমান হওয়ার আগে ক্যু ডেটা লেখার বিষয়টি বিশ্বব্যাপী দৃশ্যমান তা নিশ্চিত করতে অবশ্যই অস্থির হতে হবে head
।
উদ্বায়ী শব্দ উভয় জাভা এবং C # বিভিন্ন অর্থ রয়েছে।
জাভা ভাষার বিশেষ থেকে :
কোনও ক্ষেত্রকে অস্থির হিসাবে ঘোষণা করা যেতে পারে, সেই ক্ষেত্রে জাভা মেমরি মডেল নিশ্চিত করে যে সমস্ত থ্রেড চলকটির জন্য একটি সামঞ্জস্যপূর্ণ মান দেখতে পাবে।
উদ্বায়ী কীওয়ার্ডের সি # রেফারেন্স থেকে :
অস্থিতিশীল কীওয়ার্ডটি ইঙ্গিত দেয় যে অপারেটিং সিস্টেম, হার্ডওয়্যার বা একযোগে সম্পাদনকারী থ্রেডের মতো কোনও কিছু দ্বারা প্রোগ্রামে কোনও ক্ষেত্রটি পরিবর্তন করা যেতে পারে।
জাভাতে, "ভোল্টাইল" JVM কে বলার জন্য ব্যবহার করা হয় যে চলকটি একই সাথে একাধিক থ্রেড দ্বারা ব্যবহৃত হতে পারে, সুতরাং নির্দিষ্ট সাধারণ অপ্টিমাইজেশন প্রয়োগ করা যায় না।
লক্ষণীয় যে একই ধরণের দুটি থ্রেড অ্যাক্সেস করে একই মেশিনে পৃথক সিপিইউতে চলছে। সিপিইউর পক্ষে আটকানো ডেটাটি আক্রমণাত্মকভাবে ক্যাশে করা খুব সাধারণ কারণ মেমরি অ্যাক্সেস ক্যাশে অ্যাক্সেসের চেয়ে খুব ধীর। এর অর্থ হ'ল যদি সিপিইউ 1 তে ডেটা আপডেট করা থাকে তবে তা অবশ্যই ক্যাশে নিজেকে সাফ করার সিদ্ধান্ত নেওয়ার পরিবর্তে সমস্ত ক্যাশে এবং প্রধান স্মৃতিতে যেতে হবে, যাতে সিপিইউ 2 আপডেটের মানটি দেখতে পারে (পথে সমস্ত ক্যাশে উপেক্ষা করে)।
আপনি যখন অ-উদ্বায়ী ডেটা পড়ছেন তখন এক্সিকিউটিভ থ্রেড সর্বদা আপডেট হওয়া মানটি পেতে পারে বা নাও পারে। তবে যদি বস্তুটি অস্থির হয় তবে থ্রেড সর্বদা সর্বাধিক আপ টু ডেট মান।
অস্থিরতা সম্মতি সমস্যা সমাধান করছে। সিঙ্কে যে মান করতে। এই কীওয়ার্ডটি বেশিরভাগ থ্রেডিংয়ে ব্যবহৃত হয়। যখন একাধিক থ্রেড একই পরিবর্তনশীল আপডেট করে।