জাভাতে অস্থির বনাম স্ট্যাটিক


265

এটি কি ঠিক বলা যায় যে এর staticঅর্থ সমস্ত বস্তুর জন্য মূল্যের volatileএকটি অনুলিপি এবং তার অর্থ সমস্ত থ্রেডের মানটির একটি অনুলিপি?

যাইহোক একটি staticপরিবর্তনশীল মানও সমস্ত থ্রেডের জন্য একটি মান হতে চলেছে, তবে আমরা কেন যাব volatile?


এর উদ্বায়ী অফিসিয়াল ব্যাখ্যা: cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile
Vadzim

উত্তর:


365

জাভাতে স্ট্যাটিক ভেরিয়েবল ঘোষণার অর্থ এই যে শ্রেণীর কতগুলি বস্তু তৈরি হয় তা বিবেচনা না করে কেবল একটি অনুলিপি থাকবে। ভেরিয়েবল অ্যাক্সেসযোগ্য এমনকি কোনও 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ক্লাস ব্যবহার করুন ।


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

5
আপনি "স্থানীয়ভাবে ক্যাশেড" বললে ক্যাশেটি কী? সিপিইউ ক্যাশে, একরকম জেভিএম ক্যাশে?
ইন ইন

6
@মার্টিনান হ্যাঁ, চলকটি প্রসেসর বা কোরের কাছাকাছি ক্যাশে থাকতে পারে। আরও তথ্যের জন্য cs.umd.edu/~pugh/java/mmoryModel/jsr-133-faq.html দেখুন ।
stivlo

15
'উদ্বায়ী' প্রতি বস্তুর জন্য একটি পরিবর্তনশীল বোঝায় না । 'স্ট্যাটিক' এর অনুপস্থিতি তা করে। ওপির পক্ষ থেকে এই প্রাথমিক ভুল ধারণাটি পরিষ্কার করতে ব্যর্থ হওয়ার জন্য -1।
লার্নের মারকুইস

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

288

স্থির এবং অস্থির মধ্যে পার্থক্য:

স্ট্যাটিক ভেরিয়েবল : যদি দুটি থ্রেড (ধরুন t1এবং t2) একই বস্তুতে অ্যাক্সেস করছে এবং স্থিতিশীল হিসাবে ঘোষিত এমন একটি ভেরিয়েবল আপডেট করছে তবে তার অর্থ t1এবং t2একই জিনিসটির নিজস্ব স্থানীয় অনুলিপি (স্ট্যাটিক ভেরিয়েবল সহ) তাদের নিজ নিজ ক্যাশে তৈরি করতে পারে, সুতরাং আপডেট করুন t1এটির স্থানীয় ক্যাশে স্থির পরিবর্তনশীল দ্বারা তৈরি করা ক্যাশের স্থিতিশীল ভেরিয়েবলের প্রতিফলন ঘটায় না t2

স্ট্যাটিক ভেরিয়েবলগুলি অবজেক্টের প্রসঙ্গে ব্যবহার করা হয় যেখানে এক বস্তুর দ্বারা আপডেট করা একই শ্রেণীর অন্যান্য সমস্ত অবজেক্টে প্রতিফলিত হবে তবে থ্রেডের প্রসঙ্গে নয় যেখানে স্ট্যাটিক ভেরিয়েবলের এক থ্রেডের আপডেটগুলি সমস্ত পরিবর্তনের সাথে সাথে পরিবর্তনগুলি প্রতিফলিত করবে থ্রেড (তাদের স্থানীয় ক্যাশে)।

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


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

@ জয়করত হ্যাঁ এটি আমার জন্য খুব বিভ্রান্তিকর ছিল। আমার বোধগম্যতা হ'ল আপনি ঠিক বলেছেন এবং এই উত্তরটি ভুল হিসাবে লেখা আছে। আমি ভুল হলে আমিও সংশোধন করতে চাই।
স্টুয়ার্ট

@ জয়করত থ্রেডগুলি স্থির ভেরিয়েবলগুলি ক্যাশে করে না তবে আপডেট স্ট্যাটিক ভেরিয়েবলগুলি উল্লেখ করে।
সোম

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

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

32

অন্যান্য উত্তরের পাশাপাশি, আমি এটির জন্য একটি চিত্র যুক্ত করতে চাই (ছবিটি বোঝা সহজ করে তোলে)

এখানে চিত্র বর্ণনা লিখুন

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

volatileঘোষণাটি নিশ্চিত করে যে থ্রেডগুলি ডেটা ক্যাশে করবে না এবং কেবল ভাগ করা অনুলিপি ব্যবহার করবে

চিত্র উত্স


1
স্ট্যাটিক ভেরিয়েবলগুলি কোনও থ্রেডের নীচে বস্তুর মধ্যে ভাগ করা হয়? এটি স্টাডিক ভেরিয়েবলগুলি থ্রেড নির্বিশেষে সমস্ত বস্তুর মধ্যে ভাগ করে নেওয়া উচিত should
cquezel

1
"উদ্বায়ী ভেরিয়েবলগুলি একাধিক থ্রেডের মধ্যে ভাগ করা হয় (সুতরাং বস্তুগুলিও)" একাধিক থ্রেড বা অবজেক্টের মধ্যে কীভাবে ভেরিয়েবলগুলি ভাগ করা হয় তা উদ্বায়ী হয় না। এটি কীভাবে রানটাইমকে মান ক্যাশে করার অনুমতি দেয় তা পরিবর্তন করে।
cquezel

1
স্ট্যাটিক ভেরিয়েবল সম্পর্কে আপনার মন্তব্যটি অ স্থির ক্ষেত্রেও প্রযোজ্য এবং "ক্যাশে হবে" এবং "প্রতিবিম্বিত হবে না" সম্ভবত পুনরায় করা উচিত "ক্যাশে হতে পারে" এবং "প্রতিফলিত হতে পারে না"।
cquezel

4
আমি খুব বিভ্রান্ত ছিলাম। এই ছবিটি আমার সমস্ত প্রশ্ন পরিষ্কার করেছে!
ভিনস

5

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


4

সহজ অর্থে,

  1. স্থিতিশীল : staticভেরিয়েবলগুলি কোনও বস্তুর পরিবর্তে শ্রেণীর সাথে যুক্ত হয় । শ্রেণীর প্রতিটি উদাহরণ একটি বর্গ ভেরিয়েবল শেয়ার করে, যা মেমরির এক স্থানে থাকে

  2. উদ্বায়ী : এই কীওয়ার্ডটি উভয় শ্রেণি এবং উদাহরণ ভেরিয়েবলের জন্য প্রযোজ্য ।

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

এই কটাক্ষপাত আছে নিবন্ধটি দ্বারা Javin Paul আরও উত্তম উপায়ে উদ্বায়ী ভেরিয়েবল বুঝতে।

এখানে চিত্র বর্ণনা লিখুন

volatileকীওয়ার্ডের অভাবে , প্রতিটি থ্রেডের স্ট্যাকের ভেরিয়েবলের মান আলাদা হতে পারে। ভেরিয়েবলটি হিসাবে তৈরি করে volatile, সমস্ত থ্রেডগুলি তাদের কার্যকরী স্মৃতিতে একই মান পাবে এবং মেমরির ধারাবাহিকতা ত্রুটিগুলি এড়ানো হয়েছে।

এখানে শব্দটি variableপারেন হতে পারে static(ক্লাস) পরিবর্তনশীল বা instance(বস্তু) পরিবর্তনশীল।

আপনার জিজ্ঞাসা সম্পর্কিত:

যাইহোক একটি স্ট্যাটিক ভেরিয়েবল মানও সমস্ত থ্রেডের জন্য একটি মান হতে চলেছে, তবে কেন আমরা অস্থির হয়ে যাব?

instanceআমার অ্যাপ্লিকেশনটিতে আমার যদি ভেরিয়েবলের প্রয়োজন হয় তবে আমি ভেরিয়েবলটি ব্যবহার করতে পারি না static। এমনকি staticভেরিয়েবলের ক্ষেত্রেও, ডায়াগ্রামের মতো থ্রেড ক্যাশের কারণে ধারাবাহিকতা গ্যারান্টিযুক্ত নয়।

volatileভেরিয়েবলগুলি ব্যবহার করে মেমোরি ধারাবাহিকতা ত্রুটির ঝুঁকি হ্রাস করে, কারণ কোনও অস্থির ভেরিয়েবলের কোনও লেখাই সেই একই ভেরিয়েবলের পরবর্তী পাঠগুলির সাথে ঘটে যাওয়া সম্পর্ক স্থাপন করে। এর অর্থ হল একটি অস্থায়ী পরিবর্তনশীলে পরিবর্তন সর্বদা অন্যান্য থ্রেডে দৃশ্যমান।

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

সিঙ্ক্রোনাইজড কোডের মাধ্যমে এই ভেরিয়েবলগুলি অ্যাক্সেস করার চেয়ে সাধারণ পারমাণবিক পরিবর্তনশীল অ্যাক্সেস ব্যবহার করা আরও কার্যকর

java.util.concurrentপ্যাকেজের কয়েকটি শ্রেণি পারমাণবিক পদ্ধতি সরবরাহ করে যা সুসংগতের উপর নির্ভর করে না।

আরও তথ্যের জন্য এই উচ্চ স্তরের সম্মতি নিয়ন্ত্রণ নিবন্ধটি দেখুন।

বিশেষত পরমাণু ভেরিয়েবলগুলি দেখুন

সম্পর্কিত এসই প্রশ্ন:

অস্থির বনাম পরমাণু

ভোল্টাইল বুলেটিয়ান বনাম অ্যাটমিকবুলিয়ান

জাভাতে অস্থির এবং সিঙ্ক্রোনাইজের মধ্যে পার্থক্য


আমি সত্যিই এই উত্তর প্রশংসা করি। আমি জানতাম কি volatileআগে, কিন্তু আমার জন্য এই উত্তর সুস্পষ্ট অনেক কেন আমি এখনও ব্যবহার করতে হবে volatileসঙ্গে staticপরিবর্তনশীল।
চাকলাদার আসফাক আরেফে

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

অস্থির ক্লাস (স্থির) ভেরিয়েবলের জন্য প্রযোজ্য। গুগলে ডাবল লকড সিঙ্গলটন লিঙ্কগুলির জন্য দেখুন এবং আপনি বুঝতে পারবেন যে আপনার বোঝাটি ভুল। stackoverflow.com/questions/18093735/…
রবীন্দ্র বাবু

ব্যক্তিগত স্ট্যাটিক উদ্বায়ী বৈধ ঘোষণা।
রবীন্দ্র বাবু

0

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

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

যদি কেউ স্থির পরিবর্তনশীল থেকে কাঙ্ক্ষিত ফলাফলের প্রত্যাশা করে তবে মাল্টি-থ্রেডিংয়ে স্ট্যাটিক সহ অস্থির ব্যবহার করুন তবে সমস্ত কিছু সমাধান হয়ে যাবে resolved


0

স্থির ভেরিয়েবলগুলি থ্রেড স্থানীয় মেমরির মধ্যে বা ক্যাশে আছে তা নিশ্চিত নয়। তবে যখন আমি দুটি বস্তু (টি 1, টি 2) একই বস্তু (অবজেক্ট) অ্যাক্সেস সম্পাদন করেছি এবং যখন টি 1 থ্রেড দ্বারা স্থিতিশীল ভেরিয়েবলের আপডেট করা হয় তখন এটি টি 2 এ প্রতিফলিত হয়।


-2

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

যদি কোনও ভেরিয়েবলটিকে অস্থায়ী হিসাবে ঘোষণা করা হয়, সমস্ত থ্রেডের ভেরিয়েবলের নিজস্ব কপি থাকবে তবে মূল স্মৃতি থেকে মান নেওয়া হবে o সুতরাং, সমস্ত থ্রেডে ভেরিয়েবলের মান একই হবে।

সুতরাং, উভয় ক্ষেত্রেই মূল বিষয়টি হ'ল ভ্যারিয়েবলের মান সমস্ত থ্রেডের সমান।


15
যদি কোনও ভেরিয়েবলটিকে অস্থির হিসাবে ঘোষণা করা হয়, সমস্ত থ্রেডের ভেরিয়েবলের নিজস্ব কপি থাকবে তবে মানটি মূল স্মৃতি থেকে নেওয়া হবে। => ঠিক আছে। সুতরাং, সমস্ত থ্রেডে ভেরিয়েবলের মান একই হবে। => ভুল, প্রতিটি থ্রেড একই বস্তুর জন্য একই মান ব্যবহার করবে তবে প্রতিটি বস্তুর নিজস্ব অনুলিপি থাকবে।
এসটিভ্লো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.