2011-11-18 18 views
6

यहाँ() एक मामले में जहां एक धागा सूचित इंतज़ार कर रहा है या टाइमआउट है। यहां थोड़ी देर लूप को नकली जागने के लिए जोड़ा जाता है।जावा: कैसे प्रतीक्षा में नकली Wakeup और समय समाप्ति के बीच अंतर करना()

boolean dosleep = true; 
while (dosleep){ 
    try { 
     wait(2000); 
     /** 
     * Write some code here so that 
     * if it is spurious wakeup, go back and sleep. 
     * or if it is timeout, get out of the loop. 
     */ 

    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

इस मामले में मैं एक नकली जागने और समय के बीच अंतर कैसे कर सकता हूं? यदि यह एक नकली जागृत है, तो मुझे वापस जाने और प्रतीक्षा करने की आवश्यकता है। और यदि यह एक टाइमआउट है, तो मुझे लूप से बाहर निकलना होगा।

मैं आसानी से,() को सूचित करने के मामले की पहचान क्योंकि मैं dosleep चर की स्थापना की जाएगी करने के लिए झूठी जबकि सूचित() कॉल कर सकते हैं।

संपादित करें: मैं 1.4 जावा संस्करण का उपयोग कर रहा हूँ, एम्बेडेड परियोजना आवश्यकता की वजह से। मैं Condition का उपयोग नहीं कर सकता क्योंकि यह केवल 1.5 पोस्ट उपलब्ध है।

अग्रिम धन्यवाद।

+0

ब्रिंगर 128 का एक उचित समाधान है, लेकिन, मैं सवाल करता हूं कि आप ऐसा क्यों करना चाहते हैं। इंटरप्ट आमतौर पर "नकली जागरूकता" नहीं होता है, यह प्रक्रिया को बाधित करने और _stop_ प्रक्रिया के संकेत है। – user949300

+0

यह बाधा के बारे में नहीं है। एक "नकली wakeupup" किसी भी समय आ सकता है। अगर मैं प्रतीक्षा() में प्रवेश करने के बाद एक ही समय में आता हूं, तो मैं लूप से बाहर निकलना नहीं चाहता हूं। मुझे यह देखने की ज़रूरत है कि मैं लूप –

+0

से बाहर निकलने से पहले मैं समय-समय पर 'टाइमआउट' समय प्रतीक्षा करता हूं। आप बाधित नहीं हो रहे हैं, लेकिन कुछ अन्य थ्रेड अधिसूचना() को सूचित करते हैं, या अधिक संभावना है, सभी को सूचित करें(), और आप जागृत हो जाते हैं। – user949300

उत्तर

4

का उदाहरण है यदि आप दो मामलों को अलग करना चाहते हैं तो आपको अपने टाइमआउट का ट्रैक रखना होगा।

long timeout = 2000; 
long timeoutExpires = System.currentTimeMillis() + timeout; 
while(dosleep) { 
    wait(timeout); 
    if(System.currentTimeMillis() >= timeoutExpires) { 
    // Get out of loop 
    break; 
    } 
} 

जिसके अनुसार, Condition वर्ग का उपयोग कर के डेनिस की सिफारिश यह करने के लिए बेहतर तरीका है।

+0

नकली जागरूकता के बाद यह कोड पूरे टाइमआउट के लिए फिर से इंतजार कर रहा है और यह सही नहीं है। कैमरून स्किनर की प्रतिक्रिया सही है और जेडीके वी 4 के साथ भी पिछड़ा संगत है (जबकि डेनिस। सोलोनेंको का जवाब भी सही है, यह 'जावा.कॉन्कुरेंसी' एपीआई का उपयोग करता है और इस प्रकार, जेडीके वी 5 + की आवश्यकता होती है)। यह विषय के लिए मेरा थोड़ा सा है। –

+2

System.currentTimeMillis() का उपयोग न करें, इसके बजाय कुछ प्रकार के मोनोटोनिक समय का उपयोग करें क्योंकि सिस्टम घड़ी बदल जाने पर यह गलत व्यवहार करने की संभावना है। http://stackoverflow.com/questions/351565/system-currenttimemillis-vs-system-nanotime –

+0

जैसा कि जिरी पटेरा ने बताया है, उदाहरण स्वयं में त्रुटिपूर्ण है। इसके अलावा, "कंडीशन क्लास" वास्तव में एक इंटरफेस होने के अलावा, [हालत] का जावाडॉक (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html) स्पष्ट रूप से कहता है कि 'नकली जागरूकता की संभावना को दूर करने के लिए एक कार्यान्वयन मुक्त है लेकिन यह अनुशंसा की जाती है कि अनुप्रयोग प्रोग्रामर हमेशा मान लें कि वे हो सकते हैं और हमेशा लूप में प्रतीक्षा करें। कैमरून स्किनर का एकमात्र सही जवाब है। –

4

मुझे विश्वास है कि Lock एस और Condition इस मामले में आपकी आवश्यकता के अनुरूप बेहतर होगा। कृपया Condition.awaitUntil() के लिए javadocs जांचें - इसमें

+1

मैं 1.4 जावा संस्करण का उपयोग कर रहा हूँ, एम्बेडेड परियोजना की आवश्यकता के कारण। मुझे डर है कि हालत केवल 1.5 के बाद उपलब्ध है। –

6

आप ऐसा कर सकता है:

boolean dosleep = true; 
long endTime = System.currentTimeMillis() + 2000; 
while (dosleep) { 
    try { 
     long sleepTime = endTime - System.currentTimeMillis(); 
     if (sleepTime <= 0) { 
      dosleep = false; 
      } else { 
      wait(sleepTime); 
     } 
    } catch ... 
} 

कि जावा 1.4 में ठीक काम करना चाहिए, और यह सुनिश्चित करेगा कि आपके धागा कम से कम 2000ms के लिए सोता है।

संबंधित मुद्दे