Search code examples
javastringthread-safetyimmutabilityreentrantlock

How to set/get string in Java safely?


I have read Java String class is immutable and thread-safe but I am still confused about whether the reference assignment for Strings is thread-safe or not.

First question: If thread A calls Foo.setString() while thread B calls Foo.getString(), is following code thread-safe?

Class Foo {
    String aString;
    public String getString() {
        return aString;
    }
    public void setString(s) {
        aString = s;
    }
}

Second question: If the above code is not thread-safe, using a ReentrantLock, how do I write the Foo.getString() method?

Class Foo {
    String aString;
    ReentrantLock aLock;
    public String getString() {
        aLock.lock();
        return aString;
        aLock.unlock(); // This line will be unreachable. How to fix??
    }
    public void setString(s) {
        aLock.lock();
        aString = s;
        aLock.unlock();
    }
}

I have to use a ReentrantLock because I need to use the tryLock(timeout) feature.


Solution

  • Question 1: It depends what you mean by thread safe, Eric Lippert wrote a very good blog post about it here... But declaring aString as volatile will mean that any reads on different threads are guaranteed to be correct.

    Question 2:

    Use a try... finally construct, unlocking in the finally block eg:

    public String getString() {
      try {        
        aLock.lock();
        return aString;
      } finally {
        aLock.unlock();
      }
    }
    
    public void setString(s) {
      try {        
        aLock.lock();
        aString = s;
      } finally {
        aLock.unlock();
      }
    }