2009-10-12 16 views
28

के लिए मॉनीटर प्राप्त करने में विफल क्यों ऐसा हो सकता है?java.lang.IllegalMonitorStateException: (m = null)

java.lang.IllegalMonitorStateException: (m=null) Failed to get monitor for (tIdx=60) 
     at java.lang.Object.wait(Object.java:474) 
     at ... 

कोड है कि भड़काती यह एक सरल पूल समाधान है:

public Object takeObject() { 
     Object obj = internalTakeObject(); 
     while (obj == null) { 
      try { 
       available.wait(); 
      } catch (InterruptedException e) { 
       throw new RuntimeException(e); 
      } 
      obj = internalTakeObject(); 
     } 
     return obj; 
    } 

    private Object internalTakeObject() { 
     Object obj = null; 
     synchronized (available) { 
      if (available.size() > 0) { 
       obj = available.keySet().iterator().next(); 
       available.remove(obj); 
       synchronized (taken) { 
        taken.put(obj, Boolean.valueOf(true)); 
       } 
      } 
     } 
     return obj; 
    } 

    public void returnObject(Object obj) { 
     synchronized (taken) { 
      taken.remove(obj); 
     } 
     synchronized (available) { 
      if (available.size() < size) { 
       available.put(obj, Boolean.valueOf(true)); 
       available.notify(); 
      } 
     } 
    } 

मैं कुछ याद आ रही हूँ बात यह है कि मॉनिटर वस्तु पक्का रिक्त नहीं है, लेकिन अभी भी यह अपवाद अक्सर मिलता है ?

संपादित करें: अपवाद available.wait(); लाइन में होता है।

+0

क्या आप हमें बता सकते हैं कि स्रोत कोड में 474 कौन सी रेखा है? – flybywire

+0

अपवाद उपलब्ध है। Wait(); लाइन, लेकिन लाइन 474 java.lang.Object वर्ग से है। –

उत्तर

53

में होना चाहिए Object.wait के लिए जावाडोक देखें।

विशेष रूप से "वर्तमान धागे को इस ऑब्जेक्ट के मॉनीटर का स्वामित्व होना चाहिए।" और "[फेंकता है] अवैध मॉनिटरस्टेट अपवाद - यदि वर्तमान धागा ऑब्जेक्ट के मॉनीटर का स्वामी नहीं है।" यही है, आपको जिस ऑब्जेक्ट पर कॉल करने जा रहे हैं उस पर आपको सिंक्रनाइज़ करने की आवश्यकता है।

तो अपने कोड होना चाहिए:

synchronized (available) { 
    available.wait(); 
} 
+3

जानने के लायक: यदि यह अपवाद 'उपलब्ध.notify()' पर होता है तो उसी पैटर्न का उपयोग करें। –

+0

मैंने एक ही काम करने के लिए ब्लॉक के बजाय एक सिंक्रनाइज़ फ़ंक्शन का उपयोग करने का प्रयास किया, लेकिन यह IllegalMonitorStateException को फेंक दिया। ऐसा क्यों है? –

+0

हंटर, जब आप एक सदस्य फ़ंक्शन सिंक्रनाइज़ करते हैं तो आप ऑब्जेक्ट पर लॉक ले रहे हैं - इसलिए 'this.wait()' को काम करना चाहिए। क्या * तुमने * क्या किया? – tgdavies

6

available.wait(); एक तुल्यकालन (उपलब्ध) अनुभाग

0

takeObject() विधि सिंक्रनाइज़ किया जाना चाहिए या, हम इस पद्धति के अंदर सिंक्रनाइज़ ब्लॉक लिखने के लिए की है। मुझे उम्मीद है कि आपको इसके लिए समय अपवाद संकलित करना चाहिए।

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