Question about 20.1 Implement caching for a multithreaded dictionary

#1

From page 439:

Note that we have to clone closestToLastWord when assigning to result since otherwise closestToLastWord might change before we encode it into the response.

and code:

public static void service(ServiceRequest req, ServiceResponse resp) {
    String w = req.extractWordToCheckFromRequest();
    String [] result  = null;
    synchronized (S2.class) {
      if (w.equals(wLast)) {
        result = Arrays.copyOf(closestToLastWord, closestToLastWord.length);
      }
    }
    if (result == null) {
      result = Spell.closestInDictionary(w);
      synchronized (S2.class) {
        wLast = w;
        closestToLastWord = result;
      }
    }
    resp.encodeIntoResponse(result);
  }

It seems to me that it is not necessary to clone closestToLastWord even when closestToLastWord may be changed to point to another new array. The old closestToLastWord (pointed by result) should still be intact. Am I missing anything?

0 Likes

#2

suppose we have two concurrent calls to service() and the calls to the two synchronized blocks were interleaved as follows: T1 runs the first sync block, then T2 runs both sync blocks, then T1 runs the last sync block, T1 will read the closestToLastWord written by T2 (which will correspond to its w). note that closestToLastWord is a global.

does that make sense?

bye,
adnan

0 Likes

#3

Hi adnan,

No. It does not make sense to me. In the 2nd sync block, closestToLastWord is only written but never read by T1. The response of T1 depends entirely on the assignment of result in 1st sync block. That’s why I think it is not necessary to clone closestToLastWord.

0 Likes

#4

sorry, you are correct. i was thinking that the program was updating the array entries in closestToLastWord, but it’s actually assigning closestToLastWord. the mental model i had is illustrated in the code snippet below, and you can see how if we updated closestToLastWord instead of assigning to it, we’d clobber the first result.

thanks for your sharp eyes,

bye,
adnan

public class Race {
public static char[] closestToLastWord = new char[3];
public static int primitiveTypeVar;

public static void main(String[] args) {

    closestToLastWord[0] = 'a';
    char[] result1 = closestToLastWord;
    primitiveTypeVar = 0;
    int p1 = primitiveTypeVar;

    closestToLastWord[0] = 'x';
    char[] result2 = closestToLastWord;
    primitiveTypeVar = 1;
    int p2 = primitiveTypeVar;

    System.out.println("result1[0] = " + result1[0]); // both are 'x' since result is reference type
    System.out.println("result2[0] = " + result2[0]);

    System.out.println("p1 = " + p1); // since primitveTypeVar is of type int which is primitive first is 0, second is 1
    System.out.println("p2 = " + p2);
}

}

0 Likes