Thread Status Monitor. How do I debug this? What's causing it?
Asked Answered
W

1

6

I'm developing on Android and I can't figure out why some of my threads are going into a "monitor" status. I've read it could be because of a "synchronized" issue but I'm not sure how an object wouldn't release their lock.

Can anyone help with how to debug this or do you see anything I'm doing wrong? Is it an issue of synchronized objects not being released or is my loading not timing out properly and locking all the threads?

enter image description here

Here's how I'm using synchronized.

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

and here:

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

and here's my 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);
}

and this is how I'm loading the image from the 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);
    }
}
Wheelbarrow answered 24/8, 2012 at 19:30 Comment(6)
Is there an actual problem occurring (e.g. deadlock) or does the code run fine?Diamonddiamondback
doesn't the thread status that's circled in red above as being "monitor" mean deadlock?Wheelbarrow
I meant are you actually getting a deadlock when running the application (without debugging)?Diamonddiamondback
yes (filling space 1234567890)Wheelbarrow
what is this? state = State.COMPLETE; if (state != State.CANCELED) {Glowworm
"monitor" may mean deadlock but it also means that the threads are blocked on that monitor. It may be that the threads are looping so much that they always seem to be in that state but really they are getting time inside of the synchronized block.Ossuary
G
2

A way to check if it's indeed a deadlock is to use Android Studio's debugger: view the threads, right click on the threads that are in the "MONITOR" state and then click "Suspend." The debugger will take you to the line in the code at which the thread is stuck.

enter image description here

When I was debugging my deadlock, both threads turned out to be waiting on the synchronized statements.

Geometric answered 14/5, 2016 at 23:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.