ওপির প্রশ্নের জবাব দেওয়া
এলোমেলোভাবে কোনও ঘটনার জন্য চিরকালের জন্য অপেক্ষা না করে এই প্রত্যাশা জাগাতে আমি কী করতে পারি?
, কোনও উত্সাহী জাগরণ নেই এই অপেক্ষার থ্রেড জাগাতে পারে না!
কিনা কৃত্রিম wakeups বা ওপি একটি ক্ষেত্রে একটি নির্দিষ্ট প্ল্যাটফর্মে ঘটবে না পারে, তথাপি এর snippet ইতিবাচক হয় অসম্ভব জন্যCondition.await() ফিরে যাওয়ার এবং লাইন দেখার জন্য "কৃত্রিম ওয়েকআপ!" আউটপুট প্রবাহে।
আপনি যদি না খুব বিদেশী জাভা ক্লাস লাইব্রেরি ব্যবহার করছেন
এর কারণ হল মান হল OpenJDK এর ReentrantLock'র পদ্ধতি newCondition()আয় AbstractQueuedSynchronizer' এর গুলি বাস্তবায়ন Conditionইন্টারফেস, নেস্টেড ConditionObject(উপায় দ্বারা, এটি একমাত্র বাস্তবায়ন Conditionএই শ্রেণীর লাইব্রেরিতে ইন্টারফেস), এবং ConditionObjectএর পদ্ধতিawait() নিজেই কিনা তা পরীক্ষা শর্ত না ধারণ করে এবং কোনও উত্সাহী জাগ্রত এই পদ্ধতিটি ভুল করে ফিরে আসতে বাধ্য করতে পারে না।
যাইহোক, আপনি নিজে এটি পরীক্ষা করতে পারেন কারণ একবার AbstractQueuedSynchronizerভিত্তিযুক্ত বাস্তবায়ন জড়িত থাকার পরে উত্সাহী জাগরণ অনুকরণ করা বেশ সহজ ।
AbstractQueuedSynchronizerনিম্ন স্তরের ব্যবহার LockSupportএর parkএবং unparkপদ্ধতি, এবং যদি আপনি ডাকা LockSupport.unparkএকটি থ্রেডে অপেক্ষা উপর Condition, এই ক্রিয়াটির একটি কৃত্রিম ওয়েকআপ থেকে আলাদা করা যাবে না।
ওপির স্নিপেটটি সামান্যভাবে রিফ্যাক্টরিং,
public class Spurious {
private static class AwaitingThread extends Thread {
@Override
public void run() {
Lock lock = new ReentrantLock();
Condition cond = lock.newCondition();
lock.lock();
try {
try {
cond.await();
System.out.println("Spurious wakeup!");
} catch (InterruptedException ex) {
System.out.println("Just a regular interrupt.");
}
} finally {
lock.unlock();
}
}
}
private static final int AMOUNT_OF_SPURIOUS_WAKEUPS = 10;
public static void main(String[] args) throws InterruptedException {
Thread awaitingThread = new AwaitingThread();
awaitingThread.start();
Thread.sleep(10000);
for(int i =0 ; i < AMOUNT_OF_SPURIOUS_WAKEUPS; i++)
LockSupport.unpark(awaitingThread);
Thread.sleep(10000);
if (awaitingThread.isAlive())
System.out.println("Even after " + AMOUNT_OF_SPURIOUS_WAKEUPS + " \"spurious wakeups\" the Condition is stil awaiting");
else
System.out.println("You are using very unusual implementation of java.util.concurrent.locks.Condition");
}
}
, এবং আনপার্কিং (মূল) থ্রেডটি অপেক্ষমান থ্রেডটি জাগ্রত করার চেষ্টা করুক না কেন, Condition.await()পদ্ধতিটি এই ক্ষেত্রে আর ফিরে আসবে না।
উপর কৃত্রিম wakeups Conditionএর অপেক্ষা পদ্ধতি আলোচনা করা হয়েছে এর javadoc Conditionইন্টারফেস । যদিও এটি বলে যে,
যখন কোনও শর্তের অপেক্ষায়, একটি উত্সাহী জাগ্রত হওয়ার অনুমতি দেওয়া হয়
এবং সেটা
এটি প্রস্তাবিত হয় যে অ্যাপ্লিকেশন প্রোগ্রামাররা সবসময় ধরে নেয় যে তারা ঘটতে পারে এবং তাই সর্বদা একটি লুপে অপেক্ষা করুন।
তবে এটি পরে যুক্ত করে
উদ্দীপনা জাগ্রত হওয়ার সম্ভাবনা অপসারণের জন্য একটি বাস্তবায়ন নিখরচায়
এবং ইন্টারফেসের AbstractQueuedSynchronizerবাস্তবায়ন Conditionঠিক তা করে - উত্সাহী জাগরণের কোনও সম্ভাবনা সরিয়ে দেয় ।
এটি অবশ্যই অন্যের জন্য সত্যকে ধারণ করে ConditionObject অপেক্ষার পদ্ধতির ক্ষেত্রে ।
তাহলে উপসংহারটি হল:
আমাদের সর্বদা Condition.awaitলুপে কল করা উচিত এবং শর্তটি ধরে রাখে না কিনা তা খতিয়ে দেখা উচিত, তবে স্ট্যান্ডার্ড, ওপেনজেডিকে, জাভা ক্লাস লাইব্রেরিটি কখনই ঘটতে পারে না । যদি না আবার আপনি খুব অসাধারণ জাভা ক্লাস লাইব্রেরি ব্যবহার করেন (যা অবশ্যই খুব অস্বাভাবিক হতে হবে, কারণ অন্য একটি সুপরিচিত নন-ওপেনজেডি কে জাভা ক্লাস লাইব্রেরিগুলি, বর্তমানে প্রায় বিলুপ্ত জিএনইউ ক্লাসপাথ এবং অ্যাপাচি হারমোনিগুলিকেCondition ইন্টারফেসের স্ট্যান্ডার্ড বাস্তবায়নের অনুরূপ বলে মনে হচ্ছে )
pthread_cond_wait()আসল প্রশ্নটি ব্যবহার করে এমন জেভিএমগুলির জন্য "pthread_cond_wait এর কেন উত্সাহী জাগরণ রয়েছে?" ।