lundi 23 février 2015

Design: Object with single use?



Context


I have a class called ImageLoader.


When I call ImageLoader's getPicture( pictureID ), if the picture is not cached, I store pictureID in an instance variable, create a new thread which eventually calls my callback() function in this same ImageLoader class. callback() then uses this pictureID as the key to cache the picture.


Problem


Do you see the pickle? If I call getPicture( somePictureID ) twice in a row, and the callback() function for the first call hasn't happened yet, I will overwrite the previous pictureID which the callback() function will use. (See the code below if you still don't see the pickle.)


Now I know you're thinking, why don't I just add a little synchronization on the variable to make it thread-safe?


Because who knows how long the thread querying the picture will take, and that could really slow down the whole process of loading multiple images.


How I'm Thinking of Solving It


So my bright idea is to create in inner class that servers as a slave and only has a single use. I execute some function in this slave class once, and I never reuse the object.


Question


Is this an appropriate approach to solving this kind of problem? I feel like this might fall into some pattern I'm not aware of. If I'm totally off the mark with this one, can you suggest another solution?


Simplified Code



//the instance variable with a race condition
private int pictureID

//loads the image associated with the pictureID
public void getPicture( int pictureID )
{
Bitmap bitmap = cache.get( pictureID );
if ( bitmap != null )
{
//load image
return;
}

int post_params[] = { pictureID, /* more parameters */ };

this.pictureID = pictureID; //PROBLEM: race condition!
new HttpRequest( this ).execute( post_params ); //starts new thread and queries server
}

//gets called when the query finishes, json contains my image
public void callback( JSONObject json )
{
Bitmap bitmap = getBitmap( json ); //made up method to simplify code
cache.put( this.pictureID, bitmap ); //PROBLEM: race condition!

//load image
}



Aucun commentaire:

Enregistrer un commentaire