2012-08-24 6 views
5

Ich entwickle auf Android und ich kann nicht herausfinden, warum einige meiner Threads in einen "Monitor" Status gehen. Ich habe gelesen, dass es an einem "synchronisierten" Problem liegen könnte, aber ich bin mir nicht sicher, wie ein Objekt seine Sperre nicht freigeben würde.Thread Status Monitor. Wie debugge ich das? Was verursacht es?

Kann mir jemand bei der Fehlersuche helfen oder siehst du irgendwas, was ich falsch mache? Ist es ein Problem, dass synchronisierte Objekte nicht freigegeben werden oder wird das Laden nicht korrekt ausgeführt und alle Threads gesperrt?

enter image description here

Hier ist, wie ich bin mit synchronisiert.

private Bitmap getFromSyncCache(String url) { 
    if (syncCache == null) return null; 
    synchronized (syncCache) { 
     if (syncCache.hasObject(url)) { 
      return syncCache.get(url); 
     } else { 
      return null; 
     } 
    } 
} 

und hier:

bitmapLoader.setOnCompleteListener(new BitmapLoader.OnCompleteListener() { 
      @Override 
      public void onComplete(Bitmap bitmap) { 
       if (syncCache != null) { 
        synchronized (syncCache) { 
         syncCache.put(bitmapLoader.getLoadUrl(), bitmap); 
        } 
       } 
       if (asyncCache != null) addToAsyncCache(bitmapLoader.getLoadUrl(), bitmap); 
       if (onCompleteListener != null) onCompleteListener.onComplete(bitmap); 
      } 
     }); 

und hier ist mein Cache

public class MemoryCache<T> implements Cache<T>{ 

private HashMap<String, SoftReference<T>> cache; 

public MemoryCache() { 
    cache = new HashMap<String, SoftReference<T>>(); 
} 

@Override 
public T get(String id) { 
    if(!cache.containsKey(id)) return null; 
    SoftReference<T> ref = cache.get(id); 
    return ref.get(); 
} 

@Override 
public void put(String id, T object) { 
    cache.put(id, new SoftReference<T>(object)); 
} 

@Override 
public void clearCache() { 
    cache.clear(); 
} 

@Override 
public boolean hasObject(String id) { 
    return cache.containsKey(id); 
} 

und das ist, wie ich das Bild aus dem Internet bin Laden:

private void threadedLoad(String url) { 
    cancel(); 
    bytesLoaded = 0; 
    bytesTotal = 0; 
    try { 
     state = State.DOWNLOADING; 
     conn = (HttpURLConnection) new URL(url).openConnection(); 
     bytesTotal = conn.getContentLength(); 

     // if we don't have a total can't track the progress 
     if (bytesTotal > 0 && onProgressListener != null) { 
      // unused    
     } else { 
      conn.connect(); 
      inStream = conn.getInputStream(); 
      Bitmap bitmap = BitmapFactory.decodeStream(inStream); 
      state = State.COMPLETE; 
      if (state != State.CANCELED) { 
       if (bitmap != null) { 
        msgSendComplete(bitmap); 
       } else { 
        handleIOException(new IOException("Skia could not decode the bitmap and returned null. Url: " + loadUrl)); 
       } 
      } 
      try { 
       inStream.close(); 
      } catch(Exception e) { 

      } 
     } 
    } catch (IOException e) { 
     handleIOException(e); 
    } 
} 
+0

Gibt es ein tatsächliches Problem (z. B. Deadlock) oder funktioniert der Code gut? – Tudor

+0

bedeutet der oben rot eingekreiste Thread-Status "Monitor" nicht Deadlock? – user123321

+0

Ich meine, erhalten Sie tatsächlich einen Deadlock beim Ausführen der Anwendung (ohne Debugging)? – Tudor

Antwort

1

A Möglichkeit zu überprüfen, ob es sich tatsächlich um einen Deadlock handelt Android Studio-Debugger: Zeigen Sie die Threads an, klicken Sie mit der rechten Maustaste auf die Threads, die sich im Status "MONITOR" befinden, und klicken Sie dann auf "Suspend". Der Debugger bringt Sie zu der Zeile im Code, an der der Thread hängen geblieben ist.

enter image description here

Wenn ich meine Deadlock wurde das Debuggen, drehten beide Threads auf den synchronisierten Aussagen warten zu werden.