এটি কি ঠিক বলা যায় যে এর static
অর্থ সমস্ত বস্তুর জন্য মূল্যের volatile
একটি অনুলিপি এবং তার অর্থ সমস্ত থ্রেডের মানটির একটি অনুলিপি?
যাইহোক একটি static
পরিবর্তনশীল মানও সমস্ত থ্রেডের জন্য একটি মান হতে চলেছে, তবে আমরা কেন যাব volatile
?
এটি কি ঠিক বলা যায় যে এর static
অর্থ সমস্ত বস্তুর জন্য মূল্যের volatile
একটি অনুলিপি এবং তার অর্থ সমস্ত থ্রেডের মানটির একটি অনুলিপি?
যাইহোক একটি static
পরিবর্তনশীল মানও সমস্ত থ্রেডের জন্য একটি মান হতে চলেছে, তবে আমরা কেন যাব volatile
?
উত্তর:
জাভাতে স্ট্যাটিক ভেরিয়েবল ঘোষণার অর্থ এই যে শ্রেণীর কতগুলি বস্তু তৈরি হয় তা বিবেচনা না করে কেবল একটি অনুলিপি থাকবে। ভেরিয়েবল অ্যাক্সেসযোগ্য এমনকি কোনও Objects
তৈরি না করেও। তবে থ্রেডগুলিতে এর স্থানীয়ভাবে ক্যাশেড মান থাকতে পারে।
যখন কোনও ভেরিয়েবল অস্থির হয় এবং স্থিতিশীল না হয় তবে প্রত্যেকটির জন্য একটি ভেরিয়েবল থাকবে Object
। সুতরাং, উপরিভাগে এটি মনে হয় সাধারণ পরিবর্তনশীল থেকে কোনও পার্থক্য নেই তবে স্থির থেকে সম্পূর্ণ পৃথক । তবে Object
ক্ষেত্রগুলি সহ, একটি থ্রেড স্থানীয়ভাবে একটি ভেরিয়েবল মান ক্যাশে করতে পারে।
এর অর্থ হ'ল যদি দুটি থ্রেড একই সাথে একই অবজেক্টের একটি পরিবর্তনশীল আপডেট করে এবং ভেরিয়েবলটিকে অস্থির হিসাবে ঘোষণা না করা হয়, তবে থ্রেডগুলির একটিতে ক্যাশের মধ্যে একটি পুরানো মান রয়েছে এমন একটি মামলা হতে পারে।
এমনকি যদি আপনি একাধিক থ্রেডের মাধ্যমে স্থিতিশীল মান অ্যাক্সেস করেন তবে প্রতিটি থ্রেডের স্থানীয় ক্যাশেড অনুলিপি থাকতে পারে! এটি এড়াতে আপনি পরিবর্তনশীলটিকে স্থিতিশীল অস্থির হিসাবে ঘোষণা করতে পারেন এবং এটি থ্রেডকে প্রতিবার বৈশ্বিক মান পড়তে বাধ্য করবে।
তবে, অস্থিরতা সঠিক সিঙ্ক্রোনাইজেশনের বিকল্প নয়!
এই ক্ষেত্রে:
private static volatile int counter = 0;
private void concurrentMethodWrong() {
counter = counter + 5;
//do something
counter = counter - 5;
}
concurrentMethodWrong
একযোগে অনেক সময় কার্যকর করা শূন্য থেকে আলাদা কাউন্টারের একটি চূড়ান্ত মান হতে পারে!
সমস্যা সমাধানের জন্য, আপনাকে একটি লক প্রয়োগ করতে হবে:
private static final Object counterLock = new Object();
private static volatile int counter = 0;
private void concurrentMethodRight() {
synchronized (counterLock) {
counter = counter + 5;
}
//do something
synchronized (counterLock) {
counter = counter - 5;
}
}
বা AtomicInteger
ক্লাস ব্যবহার করুন ।
স্থির এবং অস্থির মধ্যে পার্থক্য:
স্ট্যাটিক ভেরিয়েবল : যদি দুটি থ্রেড (ধরুন t1
এবং t2
) একই বস্তুতে অ্যাক্সেস করছে এবং স্থিতিশীল হিসাবে ঘোষিত এমন একটি ভেরিয়েবল আপডেট করছে তবে তার অর্থ t1
এবং t2
একই জিনিসটির নিজস্ব স্থানীয় অনুলিপি (স্ট্যাটিক ভেরিয়েবল সহ) তাদের নিজ নিজ ক্যাশে তৈরি করতে পারে, সুতরাং আপডেট করুন t1
এটির স্থানীয় ক্যাশে স্থির পরিবর্তনশীল দ্বারা তৈরি করা ক্যাশের স্থিতিশীল ভেরিয়েবলের প্রতিফলন ঘটায় না t2
।
স্ট্যাটিক ভেরিয়েবলগুলি অবজেক্টের প্রসঙ্গে ব্যবহার করা হয় যেখানে এক বস্তুর দ্বারা আপডেট করা একই শ্রেণীর অন্যান্য সমস্ত অবজেক্টে প্রতিফলিত হবে তবে থ্রেডের প্রসঙ্গে নয় যেখানে স্ট্যাটিক ভেরিয়েবলের এক থ্রেডের আপডেটগুলি সমস্ত পরিবর্তনের সাথে সাথে পরিবর্তনগুলি প্রতিফলিত করবে থ্রেড (তাদের স্থানীয় ক্যাশে)।
উদ্বায়ী ভেরিয়েবল : যদি দুটি থ্রেড (ধরা যাক t1
এবং t2
) একই বস্তুতে অ্যাক্সেস করছে এবং কোনও পরিবর্তনশীল যা অস্থায়ী হিসাবে ঘোষিত হয় তা আপডেট করা হয় তবে এর অর্থ t1
এবং এটি ভেরিয়েবল হিসাবে ঘোষিত ভেরিয়েবল ব্যতীতt2
অবজেক্টের নিজস্ব স্থানীয় ক্যাশে তৈরি করতে পারে । সুতরাং উদ্বায়ী ভেরিয়েবলের কেবলমাত্র একটি মূল অনুলিপি থাকবে যা বিভিন্ন থ্রেড দ্বারা আপডেট হবে এবং এক থ্রেড দ্বারা অস্থির ভেরিয়েবলে আপডেট করা তাত্ক্ষণিকভাবে অন্য থ্রেডের প্রতিফলিত হবে।
volatile
ভেরিয়েবল পৃথক সিপিইউ ক্যাশে ভাগ করা যায়। এটি কোনও সমস্যা উপস্থাপন করে কারণ ক্যাশে পরিবর্তন করার আগে ক্যাশে লাইনের একচেটিয়া মালিকানার বিষয়ে আলোচনা করে negoti
অন্যান্য উত্তরের পাশাপাশি, আমি এটির জন্য একটি চিত্র যুক্ত করতে চাই (ছবিটি বোঝা সহজ করে তোলে)
static
ভেরিয়েবলগুলি পৃথক থ্রেডের জন্য ক্যাশে করা যেতে পারে। মাল্টি-থ্রেড এনভায়রনমেন্টে যদি কোনও থ্রেড তার ক্যাশেড ডেটা সংশোধন করে, তবে এটির একটি অনুলিপি থাকায় এটি অন্যান্য থ্রেডের জন্য প্রতিফলিত নাও হতে পারে।
volatile
ঘোষণাটি নিশ্চিত করে যে থ্রেডগুলি ডেটা ক্যাশে করবে না এবং কেবল ভাগ করা অনুলিপি ব্যবহার করবে ।
আমি মনে করি static
এবং এর volatile
কোন সম্পর্ক নেই। আমি আপনাকে পারমাণবিক অ্যাক্সেস বুঝতে জাভা টিউটোরিয়াল পড়ার পরামর্শ দিচ্ছি এবং কেন পারমাণবিক অ্যাক্সেস ব্যবহার করবেন, কী ইন্টারলিভড রয়েছে তা বুঝতে পারেন , আপনি উত্তর পাবেন।
সহজ অর্থে,
স্থিতিশীল : static
ভেরিয়েবলগুলি কোনও বস্তুর পরিবর্তে শ্রেণীর সাথে যুক্ত হয় । শ্রেণীর প্রতিটি উদাহরণ একটি বর্গ ভেরিয়েবল শেয়ার করে, যা মেমরির এক স্থানে থাকে
উদ্বায়ী : এই কীওয়ার্ডটি উভয় শ্রেণি এবং উদাহরণ ভেরিয়েবলের জন্য প্রযোজ্য ।
উদ্বায়ী ভেরিয়েবলগুলি ব্যবহার করা স্মৃতি ধারাবাহিকতা ত্রুটির ঝুঁকি হ্রাস করে, কারণ কোনও অস্থির ভেরিয়েবলের কোনও লেখাই সেই একই ভেরিয়েবলের পরবর্তী পাঠগুলির সাথে ঘটে যাওয়ার আগে সম্পর্ক স্থাপন করে। এর অর্থ হল একটি অস্থায়ী পরিবর্তনশীলে পরিবর্তন সর্বদা অন্যান্য থ্রেডে দৃশ্যমান
এই কটাক্ষপাত আছে নিবন্ধটি দ্বারা Javin Paul
আরও উত্তম উপায়ে উদ্বায়ী ভেরিয়েবল বুঝতে।
volatile
কীওয়ার্ডের অভাবে , প্রতিটি থ্রেডের স্ট্যাকের ভেরিয়েবলের মান আলাদা হতে পারে। ভেরিয়েবলটি হিসাবে তৈরি করে volatile
, সমস্ত থ্রেডগুলি তাদের কার্যকরী স্মৃতিতে একই মান পাবে এবং মেমরির ধারাবাহিকতা ত্রুটিগুলি এড়ানো হয়েছে।
এখানে শব্দটি variable
পারেন হতে পারে static
(ক্লাস) পরিবর্তনশীল বা instance
(বস্তু) পরিবর্তনশীল।
আপনার জিজ্ঞাসা সম্পর্কিত:
যাইহোক একটি স্ট্যাটিক ভেরিয়েবল মানও সমস্ত থ্রেডের জন্য একটি মান হতে চলেছে, তবে কেন আমরা অস্থির হয়ে যাব?
instance
আমার অ্যাপ্লিকেশনটিতে আমার যদি ভেরিয়েবলের প্রয়োজন হয় তবে আমি ভেরিয়েবলটি ব্যবহার করতে পারি না static
। এমনকি static
ভেরিয়েবলের ক্ষেত্রেও, ডায়াগ্রামের মতো থ্রেড ক্যাশের কারণে ধারাবাহিকতা গ্যারান্টিযুক্ত নয়।
volatile
ভেরিয়েবলগুলি ব্যবহার করে মেমোরি ধারাবাহিকতা ত্রুটির ঝুঁকি হ্রাস করে, কারণ কোনও অস্থির ভেরিয়েবলের কোনও লেখাই সেই একই ভেরিয়েবলের পরবর্তী পাঠগুলির সাথে ঘটে যাওয়া সম্পর্ক স্থাপন করে। এর অর্থ হল একটি অস্থায়ী পরিবর্তনশীলে পরিবর্তন সর্বদা অন্যান্য থ্রেডে দৃশ্যমান।
আরও কী, এর অর্থ এটিও হ'ল যে কোনও থ্রেড যখন একটি অস্থির পরিবর্তনশীল পড়বে, তখন এটি কেবলমাত্র অস্থিরতার সর্বশেষ পরিবর্তনটিই দেখতে পাবে না তবে সেই কোডের পার্শ্ব প্রতিক্রিয়া যা পরিবর্তনের দিকে নিয়েছিল => মেমরি ধারাবাহিকতা ত্রুটিগুলি এখনও অস্থির ভেরিয়েবলের সাথে সম্ভব । পার্শ্ব প্রতিক্রিয়া এড়াতে, আপনাকে সিঙ্ক্রোনাইজড ভেরিয়েবলগুলি ব্যবহার করতে হবে। তবে জাভাতে আরও ভাল সমাধান পাওয়া যায়।
সিঙ্ক্রোনাইজড কোডের মাধ্যমে এই ভেরিয়েবলগুলি অ্যাক্সেস করার চেয়ে সাধারণ পারমাণবিক পরিবর্তনশীল অ্যাক্সেস ব্যবহার করা আরও কার্যকর
java.util.concurrent
প্যাকেজের কয়েকটি শ্রেণি পারমাণবিক পদ্ধতি সরবরাহ করে যা সুসংগতের উপর নির্ভর করে না।
আরও তথ্যের জন্য এই উচ্চ স্তরের সম্মতি নিয়ন্ত্রণ নিবন্ধটি দেখুন।
বিশেষত পরমাণু ভেরিয়েবলগুলি দেখুন ।
সম্পর্কিত এসই প্রশ্ন:
volatile
আগে, কিন্তু আমার জন্য এই উত্তর সুস্পষ্ট অনেক কেন আমি এখনও ব্যবহার করতে হবে volatile
সঙ্গে static
পরিবর্তনশীল।
উদ্বায়ী ভেরিয়েবল মান অ্যাক্সেস মূল স্মৃতি থেকে সরাসরি হবে। এটি কেবলমাত্র বহু-থ্রেডিং পরিবেশে ব্যবহার করা উচিত। স্ট্যাটিক ভেরিয়েবল একবারে লোড হবে। এটি যদি একক থ্রেড পরিবেশে ব্যবহৃত হয়, এমনকি ভেরিয়েবলের অনুলিপি আপডেট করা হবে এবং কেবলমাত্র একটি থ্রেড থাকায় এটি অ্যাক্সেস করার কোনও ক্ষতি হবে না।
এখন যদি স্ট্যাটিক ভেরিয়েবলটি মাল্টি-থ্রেডিং পরিবেশে ব্যবহৃত হয় তবে যদি কেউ এর কাছ থেকে পছন্দসই ফলাফল প্রত্যাশা করে তবে সমস্যা হবে। যেহেতু প্রতিটি থ্রেডের নিজস্ব অনুলিপি থাকে তাই এক থ্রেড থেকে স্থিতিশীল ভেরিয়েবলের কোনও বৃদ্ধি বা হ্রাস অন্য থ্রেডে প্রতিফলিত নাও হতে পারে।
যদি কেউ স্থির পরিবর্তনশীল থেকে কাঙ্ক্ষিত ফলাফলের প্রত্যাশা করে তবে মাল্টি-থ্রেডিংয়ে স্ট্যাটিক সহ অস্থির ব্যবহার করুন তবে সমস্ত কিছু সমাধান হয়ে যাবে resolved
স্থির ভেরিয়েবলগুলি থ্রেড স্থানীয় মেমরির মধ্যে বা ক্যাশে আছে তা নিশ্চিত নয়। তবে যখন আমি দুটি বস্তু (টি 1, টি 2) একই বস্তু (অবজেক্ট) অ্যাক্সেস সম্পাদন করেছি এবং যখন টি 1 থ্রেড দ্বারা স্থিতিশীল ভেরিয়েবলের আপডেট করা হয় তখন এটি টি 2 এ প্রতিফলিত হয়।
যদি আমরা কোনও ভেরিয়েবলটিকে স্থিতিশীল হিসাবে ঘোষণা করি তবে ভেরিয়েবলের কেবল একটি অনুলিপি থাকবে। সুতরাং, যখনই বিভিন্ন থ্রেড সেই পরিবর্তনশীল অ্যাক্সেস করে, ভেরিয়েবলের জন্য কেবলমাত্র একটি চূড়ান্ত মান থাকবে (যেহেতু ভেরিয়েবলের জন্য কেবলমাত্র একটি মেমরি অবস্থান বরাদ্দ থাকে)।
যদি কোনও ভেরিয়েবলটিকে অস্থায়ী হিসাবে ঘোষণা করা হয়, সমস্ত থ্রেডের ভেরিয়েবলের নিজস্ব কপি থাকবে তবে মূল স্মৃতি থেকে মান নেওয়া হবে o সুতরাং, সমস্ত থ্রেডে ভেরিয়েবলের মান একই হবে।
সুতরাং, উভয় ক্ষেত্রেই মূল বিষয়টি হ'ল ভ্যারিয়েবলের মান সমস্ত থ্রেডের সমান।