2012-08-24 13 views
5

Rozwijam się na Androida i nie mogę zrozumieć, dlaczego niektóre z moich wątków przechodzą w stan "monitorowania". Czytałem, że może to być spowodowane "zsynchronizowanym" problemem, ale nie jestem pewien, w jaki sposób obiekt nie wyda ich blokady.Monitor stanu nici. Jak mogę to debugować? Co to powoduje?

Czy ktoś może pomóc w debugowaniu tego lub czy widzisz coś, co robię źle? Czy problem z synchronizowanymi obiektami nie został zwolniony, czy moje ładowanie nie kończy się poprawnie i blokuje wszystkie wątki?

enter image description here

Oto jak używam zsynchronizowane.

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

i tutaj:

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); 
      } 
     }); 

i oto moja skrzynka

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); 
} 

i to jak ja ładuje obraz z internetu:

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

Czy występuje rzeczywisty problem (np. Impas) lub czy kod działa poprawnie? – Tudor

+0

Czy status wątku, który jest zaznaczony na czerwono powyżej, nie oznacza, że ​​"monitor" oznacza zakleszczenie? – user123321

+0

Chodziło mi o to, czy faktycznie uruchamiasz zakleszczenie podczas uruchamiania aplikacji (bez debugowania)? – Tudor

Odpowiedz

1

A sposób sprawdzić, czy rzeczywiście jest to impas Debugger Studio Android: wyświetl wątki, kliknij prawym przyciskiem myszy wątki, które są w stanie "MONITOR", a następnie kliknij "Zawieś". Debugger zabierze Cię do linii w kodzie, w którym wątek utknął.

enter image description here

Kiedy debugowanie mój impasu, oba wątki okazało się czekać na zsynchronizowanych oświadczeń.