Imagine you have a class that represents lazy loaded image. This means it only loads the image if needed and then caches it:
public class LazyImage {
//Path souldn't ever change
public final File path;
//This will be filled when the image is loaded
private Image image = null;
public LazyImage(File path) {
//I ommited some safety checks chere, like null check and existence check.
this.path = path;
}
public Image getImage() {
if(image!=null)
return image;
try {
image = ImageIO.read(path);
}
catch(IOException e) {
//Here, the class should remember that there was a problem getting the image
// and probably not try again, based on the exception type
}
}
}
If you'd use such class in more complex application, you'd soon find out you need to make it thread safe, so that there aren't multiple threads invoking image = ImageIO.read(path);
at the same time. In this particular case, you want to synchronize like this:
public final String imageMutex = "Prevents the image property from being modified multiple times.";
public Image getImage() {
if(image!=null)
return image;
//This only executes if the image was nullptr right now
synchronized(imageMutex) {
//If was blocked, check for the null once again
//most likely will not be null any more
if(image==null) {
File file = new File(path);
try {
image = ImageIO.read(file);
}
catch(IOException e) {
image=null;
image_failed = true;
}
}
}
return image;
}
I am actually not entirely sure how safe the non-synchronized if
at the beginning of the method is. But this question is about the imageMutex
variable. I can't synchronize on image
because it's null at the beginning. I also don't want to synchronize on the getImage
method, because it would block the threads even when they are just reading the image.
So how do programmers synchronize on variable , rather then specific object or method?
Actually, pretty much how you've done it!
Most of the time, the mutex (often aka "guard" in this type of context) is just Object imageLock = new Object ()
, but otherwise you've got it right.
Your image
field needs to be volatile, though, for this scheme -- called a double checked lock -- to work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.