যদি wait()
কোনও সিঙ্ক্রোনাইজড ব্লকের বাইরে ডাকার পক্ষে শব্দার্থকতা ধরে রাখা - কলারের থ্রেড স্থগিত করা সম্ভব হয় তবে সম্ভাব্য ক্ষতি কী ?
আসুন চিত্রিত করা যাক আমরা কোন সমস্যাগুলিতে চলে যাব যদি wait()
একটি সিঙ্ক্রোনাইজড ব্লকের বাইরে কোনও কংক্রিটের উদাহরণ সহ কল করা যায় ।
মনে করুন আমরা একটি ব্লকিং সারিটি প্রয়োগ করছিলাম (আমি জানি, এপিআইতে ইতিমধ্যে একটি রয়েছে :)
প্রথম প্রচেষ্টা (সিঙ্ক্রোনাইজেশন ছাড়াই) নীচের লাইনের সাথে কিছু দেখতে পেল
class BlockingQueue {
Queue<String> buffer = new LinkedList<String>();
public void give(String data) {
buffer.add(data);
notify(); // Since someone may be waiting in take!
}
public String take() throws InterruptedException {
while (buffer.isEmpty()) // don't use "if" due to spurious wakeups.
wait();
return buffer.remove();
}
}
এটিই সম্ভাব্যভাবে ঘটতে পারে:
একটি গ্রাহক থ্রেড কল করে take()
দেখে buffer.isEmpty()
।
গ্রাহক থ্রেড কল করার আগে wait()
, একটি প্রযোজক থ্রেড বরাবর আসে এবং একটি পূর্ণ give()
, অর্থাৎ,buffer.add(data); notify();
ভোক্তা থ্রেড এখন ডাকব wait()
(এবং মিস্notify()
যে শুধু বলা হত)।
যদি দুর্ভাগ্য হয় give()
তবে গ্রাহক থ্রেড কখনই জেগে ওঠে না এবং ফলস্বরূপ আমাদের কাছে একটি ডেড-লক রয়েছে বলে ফলক হিসাবে উত্পাদক থ্রেড বেশি উত্পাদন করতে পারে না ।
আপনি একবার সমস্যাটি বুঝতে পারলে সমাধানটি সুস্পষ্ট: synchronized
নিশ্চিত হওয়ার জন্য ব্যবহার notify
কখনই isEmpty
এবং এর মধ্যে কখনও ডাকা হয় না wait
।
বিশদে না গিয়ে: এই সিঙ্ক্রোনাইজেশন সমস্যাটি সর্বজনীন। মাইকেল বর্গওয়ার্ট যেমন উল্লেখ করেছেন, অপেক্ষা / বিজ্ঞপ্তি হ'ল থ্রেডের মধ্যে যোগাযোগের বিষয়ে, সুতরাং আপনি সর্বদা বর্ণিত শর্তের সাথে শেষের মতো শেষ করবেন। এই কারণেই "কেবলমাত্র সিঙ্ক্রোনাইজের অভ্যন্তরে অপেক্ষা করুন" বিধি প্রয়োগ করা হয়।
@ উইলির পোস্ট করা লিঙ্কের একটি অনুচ্ছেদে এটির সংক্ষিপ্তসার জানানো হয়েছে:
আপনার একটি নিখুঁত গ্যারান্টি দরকার যে ওয়েটার এবং নোটিফায়ার ভবিষ্যদ্বাণীটির অবস্থা সম্পর্কে একমত হন। ওয়েটার কিছুক্ষণ ঘুমানোর আগে প্রাক্টিকের অবস্থাটি কিছুক্ষণ পরীক্ষা করে দেখেন, তবে এটি ঘুমাতে যাওয়ার পরে এটি প্রাকটিকের সত্যতার উপর নির্ভর করে। এই দুটি ইভেন্টের মধ্যে দুর্বলতার একটি সময়কাল রয়েছে যা প্রোগ্রামটি ভেঙে দিতে পারে।
উত্পাদক এবং ভোক্তা যে বিষয়ে পোষ মানতে চান তা উপরের উদাহরণে রয়েছে buffer.isEmpty()
। এবং চুক্তিটি synchronized
ব্লকগুলিতে অপেক্ষা ও বিজ্ঞপ্তি সম্পাদিত হয় তা নিশ্চিত করে সমাধান করা হয়।
এই পোস্টটি এখানে একটি নিবন্ধ হিসাবে আবার লেখা হয়েছে: জাভা: কেন অপেক্ষা করতে হবে একটি সিঙ্ক্রোনাইজড ব্লকে ডাকতে হবে