Well, consider the immutable class Immutable as given below:
public final class Immutable
{
final int x;
final int y;
public Immutable(int x,int y)
{
this.x = x;
this.y = y;
}
//Setters
public int getX()
{
return this.x;
}
public int getY()
{
return this.y;
}
}
Now I am creating an object of Immutable in a class Sharable whose object is going to be shared by multiple threads:
public class Sharable
{
private static Immutable obj;
public static Immutable getImmutableObject()
{
if (obj == null) --->(1)
{
synchronized(this)
{
if(obj == null)
{
obj = new Immutable(20,30); ---> (2)
}
}
}
return obj; ---> (3)
}
}
Thread A sees the obj as null and moves into the synchronized block and creates object. Now, Since The Java Memory Model (JMM) allows multiple threads to observe the object after its initialization has begun but before it has concluded. So, Thread B could see the write to objas occurring before the writes to the fields of the Immutable. Hence Thread B could thus see a partially constructed Immutable that may well be in an invalid state and whose state may unexpectedly change later.
Isn't it making Immutable non-thread-safe ?
EDIT
OK, After having lot of look up on SO and going thorough some comments,I got to know that You can safely share a reference to an immutable object between threads after the object has been constructed. Also, as mentioned by #Makoto, it is usually required to declare the fields containing their references volatile to ensure visibility. Also , as stated by #PeterLawrey , declaring the reference to immutable object as final makes the field as thread-safe
So, Thread B could see the write to objas occurring before the writes to the fields of the Immutable. Hence Thread B could thus see a partially constructed Immutable that may well be in an invalid state and whose state may unexpectedly change later.
In Java 1.4, this was true. In Java 5.0 and above, final fields are thread safe after construction.
What you're describing here are two different things. First, Immutable is thread safe if the operations are being done to an instance of it.
Thread safety is, in part, ensuring that memory isn't accidentally overwritten by another thread. Insofar as using Immutable, you can never overwrite any data contained in an instance of it, so you can feel confident that, in a concurrent environment, an Immutable object will be the same when you constructed it to when the threads are manipulating it.
What you've got right there is a broken implementation of double-checked locking.
You're right in that Thread A and Thread B may trample the instance before it's set, thus making the whole immutability of the object Immutable completely moot.
I believe that the approach to fix this would be to use the volatile keyword for your obj field, so that Java (> 1.5) will respect the intended use of the singleton, and disallow threads to overwrite the contents of obj.
Now, having read a bit closer, it seems to be a bit wonky that you'd have an immutable singleton that required two pieces of static data for it to exist. It seems more like this would be suited towards a factory instead.
public class Sharable {
private Sharable() {
}
public static Immutable getImmutableInstance(int a, int b) {
return new Immutable(a, b);
}
}
Every instance of Immutable you get will truly be immutable - creating a new Immutable has no impact on the others, and using an instance of Immutable has no impact on any others as well.
Related
I came across the following code in an article somewhere on the Internet:
public class MyInt {
private int x;
public MyInt(int y) {
this.x = y;
}
public int getValue() {
return this.x;
}
}
The article states that
Constructors are not treated special by the compiler (JIT, CPU etc) so it is allowed to reorder instructions from the constructor and instructions that come after the constructor.
Also, this JSR-133 article about the Java Memory Model states that
A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object’s final fields.
The abovementioned MyInt instance seems immutable (except that the class is not marked final) and thread-safe, but the articles state it is not. They state that it's not guaranteed that x always has the correct value upon read.
But I thought that
only the thread that creates an object should have access to it while it is being constructed
and the Java Tutorials seem so support that.
My question is: does it mean that, with the current JMM, a thread can have access to a partially constructed object due to instruction reordering? And if yes, how? And does that mean that the statement from the Java Tutorials is simply not true?
That article is saying that if you have code like
foo = new MyInt(7);
in a class that has a field
MyInt foo;
then the instructions that amount to
(reference to new object).x = 7;
foo = (reference to new object);
could be swapped over as some kind of optimisation. This will never change the behaviour of the thread that's running this code, but it's possible that some other thread will be able to read foo after the line
foo = (reference to new object);
but before the line
(reference to new object).x = 7;
in which case it would see foo.x as 0, not 7. That is to say, that other thread could run
int bar = someObject.getFoo().getValue();
and end up with bar equal to 0.
I've never seen anything like this happen in the wild, but the author seems to know what he's talking about.
Instruction reordering alone can not lead to another thread seeing a partially constructed object. By definition, the JVM is only allowed to reorder things if they don't affect a correctly synchronized program's behaviour.
It's unsafe publishing of the object reference that enables bad things to happen. Here's a particularly poor attempt at a singleton for example:
public class BadSingleton {
public static BadSingleton theInstance;
private int foo;
public BadSingleton() {
this.foo = 42;
if (theInstance == null) {
theInstance = this;
}
}
}
Here you accidentally publish the reference to the object being constructed in a static field. This would not necessarily be a problem until the JVM decides to reorder things and places this.foo = 42 after the assignment to theInstance. So the two things together conspire to break your invariants and allow another thread to see a BadSingleton.theInstance with its foo field uninitialised.
Another frequent source of accidental publication is calling overrideable methods from the constructor. This does not always lead to accidental publication, but the potential is there, hence it should be avoided.
only the thread that creates an object should have access to it while it is being constructed
And does that mean that the statement from the Java Tutorials is
simply not true?
Yes and no. It depends on how we interpret the word should. There is no guarantee that in every possible case another thread won't see a partially constructed object. But it's true in the sense that you should write code that doesn't allow it to happen.
For the following simplified class:
public class MutableInteger {
private int value;
public MutableInteger(int initial) {
synchronized(this) { // is this necessary for memory visibility?
this.value = initial;
}
}
public synchronized int get() {
return this.value;
}
public synchronized void increment() {
this.value++;
}
...
}
I guess the general question is for mutable variables guarded by synchronization is it necessary to synchronize when setting the initial value in the constructor?
You're right, without the synchronized block in the constructor there is no visibility guarantee for non-final fields, as can be seen in this example.
However in practice I would rather use volatile fields or the Atomic* classes in situations like this.
Update: It is also important to mention here that in order for your program to be correctly synchronized (as defined by the JLS), you will need to publish the reference to your object in a safe manner. The cited example doesn't do that, hence why you may see the wrong value in non-final fields. But if you publish the object reference correctly (i.e. by assigning it to a final field of another object, or by creating it before calling Thread.start()), it is guaranteed that your object will be seen at least as up-to-date as the time of publishing, therefore making the synchronized block in the constructor unnecessary.
Though you've accepted an answer, let me add my two cents.
Based on what I've read, synchronization or making the field volatile would not grantee the following visibility.
A thread T1 may see a not-null value for this, but unless you've made the field value final, there's a good chance of thread T1 seeing the default value of value.
The value could be a volatile or been accessed within synchronized blocks (monitor acquire and release), either way provided that the correct execution order was followed, there's happens-before edge from the write to the read of value. There's no argument on that.
But it's not the happens before edge that we have to consider here, but the correct publication of the object itself(MutableInteger).
Creating an object is twofold where the JVM first allocates a heap space and then start initializing fields. A thread may see a not-null reference of an object but an uninitialized field of that as long as the said field is not final (Assuming reference has been correctly published).
For the following class, what are the implications of making mNumSides final? Is "thread-safety" affected?
class Shape {
private int mNumSides;
public Shape(int numSides) {
mNumSides = numSides;
}
public int getNumSides() {
return mNumSides;
}
}
Absolutely. final keyword guarantees that all the threads see the same value of mNumSides at all the times. More information on final and its impact on the Memory Model here.
Without using final the object might be inconsistently published to other threads, and there is probability (extremely low though) that a thread might see the value of mNumSides as 0 rather than numSides as passed in constructor.
Making it volatile or static will also work though.
Num sides cannot be reassigned if it is declared as final. There'd be no risk of multiple threads reading different values due to it not being declared as volatile.
So, declaring the variable as final makes the class thread safe. As of now its not thread safe.
Declaring an object final keeps its reference from being reassigned, however if the object had internal data, that data could be reassigned which would not be thread-safe. This is an important point made by Colin on another answer.
In this case the data is a primitive, and so has no internal data. So here, declaring it final works fine.
This is a sentence from Java Concurrency in Practice
Shared read-only objects include immutable and effectively immutable
objects.
What are the differences between immutable and effectively immutable objects?
Instances of a class that is not extensible and whose fields are all final and themselves immutable are immutable.
Instances of a class whose fields cannot be mutated because of details of its methods are effectively immutable. For example:
final class C {
final boolean canChange;
private int x;
C(boolean canChange) { this.canChange = canChange; }
public void setX(int newX) {
if (canChange) {
this.x = newX;
} else {
throw new IllegalStateException();
}
}
}
Some instances of C are effectively immutable and some are not.
Another example is zero-length arrays. They are effectively immutable even though their containing class is not provably immutable since there is no element of them which can be changed.
Joe-E uses a verifier to prove that some classes only allow for immutable instances. Anything marked with the Immutable marker interface are checked and certain classes like String (effectively immutable since its char[] does not escape) are grandfathered in as immutable.
Joe-E: A Security-Oriented Subset of Java says
The Immutable interface, defined by the Joe-E library,
is treated specially by the language: the Joe-E verifier
checks that every object implementing this interface will
be (deeply) immutable, and raises a compile-time error if
this cannot be automatically verified.
Here's my understanding from a bit of googling and finding this article. An Effectively Immutable Object is an object that contains fields that can be mutated, but it doesn't let anything mutate those fields because it never gives you a reference to them. For example, lets say you create a class with an ArrayList in it. ArrayLists are mutable, but if your class always returns a copy of the ArrayList and everything else in your class is immutable, then your class has become effectively immutable: There's no way to mutate the state of an instance of your class.
The blog post gives this as an example of an effectively immutable class:
import java.awt.*;
public class Line {
private final Point start;
private final Point end;
public Line(final Point start, final Point end) {
this.start = new Point(start);
this.end = new Point(end);
}
public void draw() {
//...
}
public Point getStart() {
return new Point(start);
}
public Point getEnd() {
return new Point(end);
}
}
Point objects are mutable, but that's ok, because this class does not give anyone the direct reference to it's Point instances. Instead, it returns a new instance with the same value in it. That way, nobody can mutate the state of the Line class. This makes the Line class effectively immutable.
So how is this different from a truly immutable class? A truly immutable class has fields that are also immutable. Lets imagine Line was truly immutable. To do that we're also going to have to imagine that Point is immutable. Making these assumptions, the getStart() method could have been able to be written like this:
public Point getStart() {
return start;
}
Take a look at this answer:
effectively immutable and immutable The difference between effectively immutable and immutable is that in the first case you still need to publish the objects in a safe way. For the truly immutable objects that isn't needed. So truly immutable objects are preferred because they are easier to publish, the reasons I stated above say why you might prefer unsynchronized publication.
https://stackoverflow.com/a/7887675/1007546
Immutable objects completely encapsulates their internal state and they do not allow modification of that state after construction (possibly with the use of final, etc) therefore they are safe to share between multiple threads because reading from a shared object is not harmful from multiple threads.
Effectively immutable objects may change their state prior to being shared between multiple threads, but after they are "published" (ie multiple references are given to several threads) they protect themselves from modification.
Immutable objects prevent you from using useful software engineering practices like lazy initialization because in order to lazy init a property or field they have to be mutable violating the carefree concurrency sharing property of them. Effectively immutable objects relax these constraints to get a best of both worlds approach by carefully knowing when they can safely modify their internal state and when it is forbidden.
I have a class A and B.
public class A() {
private static List<int> list = new ArrayList<int>();
public static List<int> getList() {
return list;
}
}
public class B() {
public void foo() {
synchronized(A.getList()) {
// DO Stuff
}
}
}
In class B where I synchronize. Does this synchronize on A's list, or on B's reference to A's list. I think it is the latter but could use some help.
If so then how do I accomplish a similar thing to this that will actually work?
Thanks!
It synchronizes on A's list. What do you mean by B's reference to A's list? It doesn't matter if you're in A using list or B using A.getList(), they both reference the same object. When you synchronize on it you'll block other threads from synchronizing on that same object, regardless of where it's referenced from.
The OP followed up with this comment:
What's weird is the behavior that I am seeing is that if I lock from within A I can actually lock it at the same time in B. Which pretty much means the synchronized has no effect. Which is why I surmised that maybe locking a reference won't work.
That can't happen with the code in the question.
But it could happen if there was a setList method in A that updated the list variable. You could then end up in a situation where the two threads were locking on different objects.
Another possibility is that you actually only have one thread that is taking a lock on the same object twice. That's normal behavior. Java primitive mutexes are reentrant; i.e. they only prevent two different threads from holding the same mutex at the same time.