2012-06-08 17 views
6

मैं जेबॉस एप्लिकेशन सर्वर में एक वेब ऐप चला रहा हूं और मैं सर्वर से इवेंट बेस प्रतिक्रिया लागू करने की कोशिश कर रहा हूं।प्रतीक्षा() पर Servlet फेंकता अपवाद

यह पूरा करने के लिए कि मैं servlets वर्ग पर .wait() और .notify() का उपयोग कर रहा हूं। मूल रूप से एक अजाक्स अनुरोध है, सर्वर पर कोई घटना होने तक wait के साथ सर्वलेट ब्लॉक और यदि notify को सर्वलेट पर निकाल दिया गया है।

Servlet.service() for servlet ProcessesServlet threw exception: java.lang.IllegalMonitorStateException 

यह भी एक प्रतीक्षा() एक HttpServlet वर्ग पर करने के लिए संभव है:

समस्या जब मैं सर्वलेट मैं पर इंतजार करते (1000 * 60) है?

उत्तर

7

किसी ऑब्जेक्ट पर प्रतीक्षा करने से पहले, आपको स्वामित्व लेना चाहिए।

यह सामान्य रूप से एक सिंक्रनाइज़ कथन के साथ किया जाता है।

synchronized (obj) { 
     try { 
      obj.wait(someTime); 
     } catch (Throwable e) { 
      e.printStackTrace(); 
     } 
    } 
+0

और मुझे सूचित करने से पहले ऐसा करना चाहिए? –

+0

[yes] (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#notify()) –

+0

कुछ ऐसा है जो मुझे नहीं मिलता है ... अगर मैं सिंक्रनाइज़ किए गए ब्लॉक का उपयोग करके कॉल करें। थ्रेड के साथ स्वामित्व लें, फिर मैं उस थ्रेड पर स्वामित्व कैसे ले सकता हूं जो कॉल करेगा। नोटिफ़ाई। मेरा मतलब है कि पहले सिंक्रनाइज़ ब्लॉक प्रतीक्षा कथन के कारण खत्म नहीं हुआ ... सही? पारस्परिक बहिष्कार नहीं होगा? –

1

जैसा कि डाइस्ट्रॉय ने कहा था, आपको उस पर "प्रतीक्षा" करने के लिए किसी ऑब्जेक्ट पर लॉक होना चाहिए। यदि किसी कारण के लिए, आप नहीं कर सकते हैं या नहीं करना चाहते हैं (जैसे कि एक ही विधि का समवर्ती एक ही वस्तु पर एक ताला प्राप्त करने की कोशिश चल), तो आप उपयोग कर सकते हैं:

try{ 
    Thread.sleep(time); 
} catch (Exception ex){ 
    Thread.interrupted(); 
} 

या एक नई वस्तु की घोषणा जिस पर एक ताला प्राप्त करने के लिए।

2

आप servlet में प्रतीक्षा (...) नहीं डाल सकते क्योंकि doPost, doGet, ... सिंक्रनाइज़ विधि नहीं हैं।

आप केवल सिंक्रनाइज़ विधि या ब्लॉक में प्रतीक्षा कर सकते हैं। तो आप एक सिंक्रनाइज़ ब्लॉक डाल सकते हैं और इसमें प्रतीक्षा कर सकते हैं। नीचे की तरह -

synchronized (object) { 
     try { 
      object.wait(1000*60); 
     } catch (Throwable ex) { 
      ex.printStackTrace(); 
     } 
    } 
2

स्वीकृत उत्तर में एक शर्त गुम है। जब भी आप प्रतीक्षा करते हैं, आपको हमेशा नकली वेकअप से बचाने के लिए एक शर्त की जांच करनी चाहिए। असल में, उन सभी मामलों में सामान्य रूप से लौटने की प्रतीक्षा की जाती है जो यह कहती है। यह किसी भी स्पष्ट कारण के लिए भी वापस आ सकता है। आपको Javadoc से पैटर्न का पालन करना चाहिए। मैं यहाँ फेंकने योग्य या कहीं भी कहीं ज्यादा पकड़ने की सिफारिश नहीं करता। इसके बजाय, केवल interruptedException पकड़ो। साथ ही, आपको यह सुनिश्चित करने की ज़रूरत है कि हालत जांच थ्रेड-सुरक्षित है। तो, उदाहरण के लिए आप निम्न कार्य कर सकते हैं:

private boolean condition; 
private Object lock = new Object(); 
private long timeout = 1000; 

public void conditionSatisfied() { 
    synchronized (lock) { 
     condition = true; 
     lock.notify(); 
    } 
} 

public void awaitCondition() { 
    synchronized (lock) { 
     while (!condition) { 
      try { 
       lock.wait(timeout); 
      } catch (InterruptedException e) { 
       // Probably throw some application specific exception 
      } 
     } 
     // Perform action appropriate to condition 
    } 
} 

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

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