2012-08-24 11 views
5

Estoy desarrollando en Android y no puedo entender por qué algunos de mis hilos pasan al estado de "monitor". He leído que podría deberse a un problema "sincronizado", pero no estoy seguro de cómo un objeto no liberará su bloqueo.Monitor de estado de subprocesos. ¿Cómo depuro esto? ¿Qué lo está causando?

¿Alguien me puede ayudar a depurar esto o ves algo que estoy haciendo mal? ¿Es un problema de que no se lanzan los objetos sincronizados o mi carga no se agota correctamente y bloquea todos los hilos?

enter image description here

Así es como estoy usando sincronizada.

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

y aquí:

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

y aquí es mi caché

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

y esto es lo que estoy cargando la imagen de la web:

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

¿Se está produciendo un problema real (por ejemplo, interbloqueo) o el código funciona correctamente? – Tudor

+0

¿no significa que el estado del hilo marcado con un círculo en rojo como "bloqueo" significa un punto muerto? – user123321

+0

Quería decir que en realidad está en un punto muerto cuando ejecuta la aplicación (sin depuración)? – Tudor

Respuesta

1

Un manera de comprobar si de hecho es un punto muerto es utilizar Depurador de Android Studio: ver los hilos, haga clic derecho en los hilos que están en el estado "MONITOR" y luego haga clic en "Suspender". El depurador lo llevará a la línea en el código en el que el hilo está atascado.

enter image description here

Cuando estaba depurando mi punto muerto, ambos hilos resultó estar esperando sobre los estados sincronizados.

Cuestiones relacionadas