6

私は Android で開発していますが、一部のスレッドが「モニター」ステータスになる理由がわかりません。「同期」の問題が原因である可能性があることを読みましたが、オブジェクトがロックを解放しない方法はわかりません。

誰でもこれをデバッグする方法を手伝ってもらえますか、それとも私が間違っていることがわかりますか? 同期されたオブジェクトが解放されないという問題ですか、それとも読み込みが適切にタイムアウトせず、すべてのスレッドがロックされているのでしょうか?

ここに画像の説明を入力

これが私が同期を使用している方法です。

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

そしてここ:

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

これが私のキャッシュです

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

そして、これは私がウェブから画像をロードする方法です:

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

1 に答える 1

2

本当にデッドロックかどうかを確認する方法は、Android Studio のデバッガを使用することです。スレッドを表示し、「MONITOR」状態のスレッドを右クリックしてから、「Suspend」をクリックします。デバッガーは、スレッドがスタックしているコード内の行に移動します。

ここに画像の説明を入力

デッドロックをデバッグしているときに、両方のスレッドが同期ステートメントを待機していることが判明しました。

于 2016-05-14T23:21:55.020 に答える