say we have this
// This is trivially immutable.
public class Foo {
private String bar;
public Foo(String bar) {
this.bar = bar;
}
public String getBar() {
return bar;
}
}
What makes this thread unsafe ? Following on from this question.
To put it simply, a class instance is immutable when its internal state can't be modified after it has been constructed. A MessageService object is effectively immutable since its state can't change after its construction. So, it's thread-safe.
No, it is not mandatory to have all properties final to create an immutable object. In immutable objects you should not allow users to modify the variables of the class. You can do this just by making variables private and not providing setter methods to modify them.
Immutable objects are useful in multithreaded applications because they can be safely accessed by several threads concurrently, without the need for locking or other synchronization.
Final variables are immutable references, so a variable declared final is safe to access from multiple threads. You can only read the variable, not write it.
Foo
is thread safe once it has been safely published. For example, this program could print "unsafe" (it probably won't using a combination of hotspot/x86) - if you make bar
final it can't happen:
public class UnsafePublication {
static Foo foo;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while (foo == null) {}
if (!"abc".equals(foo.getBar())) System.out.println("unsafe");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
foo = new Foo("abc");
}
}).start();
}
}
Due to JVM optimization, you can never assume that operations are executed in the order they are written, unless it matters for the same thread. So when you call the constructor and then pass a reference to the resulting object to another thread, the JVM might not actually write the value of foo.bar before it is needed within the same thread.
That means that in a multithreaded environment, the getBar method could be called before the value in the constructor was written to it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With