1

I have a class like the below and am wondering, will this be thread-safe or can the main thread and the Loader thread possibly have their own copys of the mCache and therefore the get(..) method fail to retreive anything from the cache as it was added in the loader thread? Do i need to mark this volatile?

Thanks!!

public class StackExample
{
    private final ConcurrentHashMap<String, SoftReference<Bitmap>> mCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>();

    private addToCache(String key, Bitmap bitmap)
    {
        mCache.put(key, bitmap);
    }

    private Bitmap getBitmap(String key)
    {
        if(mCache.contains(key))
        {
            return mCache.get(key);
        }
        else
        {
            //add to loading queue
        }
    }

    private class Loader extends Thread
    {
        @Override
        public void run() 
        {
            ...//check loading queue and load some images here
            mCache.put(keyString, new SoftReference<Bitmap>(loadedBitmap));
        }
    }
}
3
  • you'll only have a unique mCache visible to all threads but your code still isn't properly synchronized. You may enter twice (or more than that) the //add to loading queue part of your code for a same key although from your example it's not entirely clear where getBitmap is called from (it's apparently private!?). Commented Jun 29, 2011 at 15:57
  • btw +1 to your question and shame on the people who upvoted Jon Skeet's one line answer without also upvoting your very fine question. Commented Jun 29, 2011 at 15:58
  • thanks! Yes just a quick example there, i do know what you mean in regards to the get method :) Commented Jun 29, 2011 at 16:04

2 Answers 2

4

The variable is final, so it will be visible to all threads before the constructor (empty in this case) returns.

Sign up to request clarification or add additional context in comments.

6 Comments

does it not matter that it is mutable? Is a final field never susceptible to threads holding their own copys?
@Dori: What do you think would be copied? ConcurrentHashMap is mutable but designed to be used by multiple threads without locking.
sorry, i was under the probably incorrect impression that all variables were able to be held as local copyies by each thread that uses them, with resulted in a thread possibly not being able to view the changes another thread has made to that variable. In some circunstances the volatile keyword can prevent this but does not stop interleaved operations. Also i thought synchronised stopped interleaved operations but I am unsure what effect it has on the local copy/caching of variables - when the sycnronised block starts/exits does the variable get refreshed / pushed to main memory?
@Dori: But the value of the variable is only the reference - not the object. And that variable is final, so the value can't be changed. See the memory model part of the Java Language Specification for more details.
ok thanks jon, a doc i obviously need to read! I take it that if I used a normal hashMap i could run into problems here?
|
0

volatile means that each thread will not keep a cache of the value of the field. If you were able to write to the mCache field then you would declare it volatile if you wanted to be sure that another thread got the new value when reading the field immediately after it was set by another thread.

2 Comments

from the above i thought this would not fit in the case as the field is just a reference and final
exactly. No reason to declare it volatile when it cannot change

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.