简体   繁体   中英

Should I create dummy object to be able to synchronize on properties that may be null?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM