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.
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();
}
}