On 11/30/10 3:15 PM, Kenton Varda wrote:
To answer your questions:
1) It is thread-safe.
2) No locking or other synchronization overhead is involved.

The string data is stored as an Object pointer which, at any particular time,
may point at either a String or a ByteString.  When one form or the other is
requested, we convert the representation to that form if necessary, then return
it.  In other words:

   String getFoo() {
     Object ref = foo;
     if (ref instanceof String) {
       return (String) ref;
     } else {
       String str = ((ByteString) ref).toStringUtf8();
       foo = str;
       return str;

This is thread-safe because the Java memory model guarantees that pointer writes
are atomic, even for non-volatile pointers (otherwise you'd have a potential
security hole!).  If two threads happen to try to access the field at the same
time, the worst that can happen is that they will both decode the string
independently.  Since they'll get the same result, it doesn't matter which of
the two pointers is stored long-term.  (Although, clients that expect getters to
consistently return the same object, as opposed to just equal objects, may be
broken.  But people should not be doing that anyway.)

We checked with Jeremy Manson to make sure this implementation works.  Working
at Google is awesome like that.  :)

Great :) Thanks for answering my questions. I see this is the same technique String#hashCode() uses.

This looks like a very minor amount of overhead, not worth having a method that forces the conversion of all strings in a message.


You received this message because you are subscribed to the Google Groups "Protocol 
Buffers" group.
To post to this group, send email to proto...@googlegroups.com.
To unsubscribe from this group, send email to 
For more options, visit this group at 

Reply via email to