2012-08-24 5 views
5

Sto sviluppando su Android e non riesco a capire perché alcuni dei miei thread entrano in uno stato di "monitor". Ho letto che potrebbe essere a causa di un problema "sincronizzato", ma non sono sicuro di come un oggetto non rilascerebbe il loro blocco.Monitor di stato del filo. Come faccio a eseguire il debug di questo? Cosa lo sta causando?

Qualcuno può aiutare con il debug di questo o si vede qualcosa che sto facendo di sbagliato? È un problema di oggetti sincronizzati che non vengono rilasciati o il mio caricamento non ha scadenze corrette e blocca tutti i thread?

enter image description here

Ecco come sto usando sincronizzati.

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

e qui:

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

ed ecco la 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); 
} 

e questo è come sto caricando l'immagine dal 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

C'è un problema che si verifica (ad es. Deadlock) o il codice funziona correttamente? – Tudor

+0

non lo stato del thread che è cerchiato in rosso sopra come "monitor" significa deadlock? – user123321

+0

Intendo dire che stai effettivamente ottenendo un deadlock durante l'esecuzione dell'applicazione (senza debug)? – Tudor

risposta

1

A modo per verificare se è davvero un deadlock è da usare Debugger di Android Studio: visualizza i thread, fai clic con il pulsante destro del mouse sui thread che si trovano nello stato "MONITOR", quindi fai clic su "Sospendi". Il debugger ti porterà sulla riga del codice in cui il thread è bloccato.

enter image description here

Quando ero debug di mia situazione di stallo, entrambi i fili si è rivelato essere in attesa sul bilancio sincronizzati.

Problemi correlati