Is class Thread safe with instance initialization - java

I have been trying to grasp concept of multi-threading and confused about the below code:
class MyClass{
private StringBuilder content = new StringBuilder();
public void setContent(){
content.append("Some String");
content.append("more String");
}
public String getContent(){
return content.toString();
}
}
My understanding is that MyClass cannot be made thread safe just by synchronizing its setter and getter methods. Because while creating MyClass object ,content reference may have improper object initialization. To make proper initialization the content should be final.
Can anyone help me to clarify it?

My understanding is that MyClass cannot be made thread safe just by synchronizing its setter and getter methods.
That is not correct.
Provided that the reference for a MyClass instance is safely published to all threads that use it, then synchronized getters and setters will see the correct initial state for the object.
If you declare content (and any other fields) to be final you can dispense with the requirement for safe publication. However, since this is not an immutable class, it will still be necessary for the getter and setter to synchronize.
The special semantics for final fields (as described in JLS 17.5) allow truly immutable objects to be thread-safe without any synchronization overheads. But these semantics are not directly applicable in your example because the "setter" is mutating the object.
Incidentally, if content had type StringBuffer rather than StringBuilder AND the variable was final. The result would be "mostly" thread-safe without synchronized. That is because StringBuilder is thread safe for these operations. The only catch is that your "setter" is calling append twice. Without a synchronized, it would be possible for a getter to see the intermediate state of the buffer.

Immutability is not always the answer to thread-safety. Lets first examine the potential thread-safety issues in the existing code. The potential problem is when you have two threads (A, and B) accessing the setter method setContent() simultaneously. That would result in having a randomized output String that might look like Some String Some String more String Some String Some String because you have no way to ensure that more String must be added right after Some String.
That logic could be perfectly fine in your application. However, if you still need to ensure that those two append statements are added together, that is when synchronization come in place. In that case, you could synchronize the setter method to ensure that only one thread at a time can access it.
Do not worry about having null StringBuilder because your method will not be accessed without instantiating the MyClassinstance first.
Hope this helps

Immutability and Thread-Safety goes hand in hand , if you are able to make your class Immutable then its said the class will be inherently thread safe , however to achieve same is not easy.
To create immutable class in java, you have to do following steps.
Declare the class as final so it can’t be extended.
Make all fields private so that direct access is not allowed.
Don’t provide setter methods for variables
Make all mutable fields final so that it’s value can be assigned
only once.
Initialize all the fields via a constructor performing deep copy.
Perform cloning of objects in the getter methods to return a copy
rather than returning the actual object reference.
but do read this https://dzone.com/articles/do-immutability-really-means as this gives a food for thought on immutable classes

Related

Can I use setter method for a replacement of final variable In the following way

Most of us understand the consequences of shared mutability, and it is said that always prefer immutability(final modifier, set once and you can't change it) if you have a chance. I have seen few coding examples where People are actually making fields final or setters as private or even removing setters for a class (which can be DTO, Model or Entity class) and another class (a builder class which can set values once to that immutable class) is used to create and set fields of the Immutable class To ensure no other class is able to modify the state. Which seems a burden to me. SO I have come-up with this thought (below I am giving an example)
public class TestDataClass {
private String name;
public String getName() {
return name;
}
public void setName(Supplier<String> supplier) throws Exception {
if(Objects.isNull(name))
{this.name = supplier.get();return;}
throw new Exception("This field is immutable and already has a value "+this.name);
}
}
In this way either you can set values through setter like this objectOfTestDataClass.setName(() -> {return Perform_Desired_Logic;});
or
objectOfTestDataClass.setName(() ->"My Name"); if it is plain setter. Then also you dont have to create a bulder class or make setters private or omit setter method
In this way, I can get rid of variable initialization during Instantiation also once you set fields to become Immutable(I am not considering reflection).
I want your expert opinion to validate how legitimate is my thought, Can I consider this as Immutability? Am I missing something? in that case please correct me.
There are several things to note
Using a Supplier<String> instead of a String does not improve the code. There are only two cases, the intended case where the method is only executed once and the code of the supplier gets executed immediately and the erroneous case, where the supplier does not get executed, but where’s the sense in optimizing the erroneous case?
If a particular property supports being null, that approach fails to handle the case when it should be fixed to `null.
The API signature does not indicate that the class should be treated like immutable. Most readers will assume that it is mutable. So they may try to modify the object and not even notice the error if you’re going to remove the exception throwing statement, as said in a comment.
Immutable objects created by a builder are definitely completed and truly immutable once build. In contrast, your class allows the creator to forget setting some properties to fixed values, producing an actually mutable object.
Since instances of this class are not guaranteed to be immutable, they also do not have the guaranty to be thread safe that is usually associated with immutable objects.
What you wrote allows to not set more than one time a field of an object.
But it is not a way to create object with a fully initialized state as a constructor or a builder can provide.
So, if the client manipulates the object with a not complete or corrupted state, it could not work as expected.
Besides, providing setters that may be invoked by the clients at compile time but which the misuses would be known only at runtime (by throwing an exception) is not a friendly and good designed API.
Example of issue with an object that has a not complete state.
Take a Rectangle class.
It is composed of 4 mandatory information (height, weight, x and y coordinates).
These are represented by 4 instance fields :
int x, int y, int width, int height
Suppose the class provides an instance method boolean contains(Point p) to determinate if a Point (x, y coordinates) is included in it.
If you apply your method to value fields of this class, you may create Rectangle instances with incomplete/partial state.
The contains() method could not work. It should perform different checks and if a field is missing in Rectangle, it should may be even throw an exception.
Example of issue with an object which the state may be corrupted
If your object may be manipulated by multiple threads, using your way to value the fields of the object may set the object in an unexpected and inconsistent state.
Two threads may manipulate the object at the same time and changing two fields that should not be changed in this way.
To avoid it, you are forced to use explicit synchronization mechanisms for both reading and writing of fields.
Ii you use a constructor or a builder, you have not these problems as you get out of the box a complete, unmodifiable (de facto thread-safe) object with a clear API.

Best design approach for creating Immutable Class

I am reading about the specific guidelines that needs to be followed while creating Immutable Class in Effective Java.
I read that In Immutable class method should not allowed to be overridden otherwise overridden method may change the behaviour of method. Following are the design approaches available in java to solve this problem :-
We can mark class final but as per my understanding, it has a one disadvantage that it makes the class inextensible.
Secondly is to make individual methods final but I can not get other disadvantage besides that we need to individually mark each method as final in order to prevent overridding.
As per book,better approach is to make the constructor private or package-private and provide public static factory method for creating object.
My question is: Even if we include private or default constructor in the class, it cannot be extended anymore in same package (in other package in case of package-private constructor), it has a same problem which the first one had. How is it considered as the better approach than the previous ones?
An immutable object should not be extensible. Why?
Because extending it will allow either direct access to fields (if they are protected which would allow writing methods that change them), or adding state which may be mutable.
Imagine we wrote a class FlexiblyRoundableDouble that extends Double, which has an additional field roundingMode that lets us choose a "rounding mode". You could write a setter for this field, and now your object is mutable.
You can argue that if all the methods are set as final, you cannot change the original behavior of the object. The only methods that could access your roundingMode field are new methods that are not polymorphically available if you assign your object to a Double variable. But when a class's contract says that it's immutable, you make decisions based on that. For example, if you write a clone() method or copy constructor for a class that has Double fields, you know that you don't need to deep-copy the Double fields, as they do not change their state, and can therefore be safely shared between the two clones.
Also, you can write methods that return the internal object without fearing that the caller will then change that object. If the object was mutable, you'd have to make a "defensive copy" of it. But if it's immutable, it's safe to return a reference to the actual internal object.
However, what happens if someone assigned a FlexiblyRoundableDouble to one of your Double fields? That object would be mutable. The clone() would assume it isn't, it will be shared between two objects, perhaps even returned by a method. The caller would then be able to cast it back as a FlexiblyRoundableDouble, change the field... and it will affect other objects that use that same instance.
Therefore, immutable objects should be final.
All this has nothing to do with the constructor issue. Objects can be safely immutable with public constructors (as demonstrated by String, Double, Integer and other standard Java immutables). The static factory method is simply a way utilizing the fact that the object is immutable, and several other objects can hold references to it safely, to create fewer objects with the same value.
Providing a static factory method gives you room to implement the Flyweight Pattern.
They're stating that you should hide the possibility of creating a new object using a constructor, and should rather make a call to a method which checks if an object with similar state exists in the "object pool" (a map filled with objects waiting to be re-used). Not re-using immutable objects is a waste of memory; this is why String literals are encouraged, and new String() is shunned (unless needed).
class ImmutableType {
private static final Map<Definition, ImmutableType> POOL = new HashMap<>();
private final Definition definition;
private ImmutableType(Definition def) {
definition = def;
}
public static ImmutableType get(Definition def) {
if(POOL.contains(def))
return POOL.get(def);
else {
ImmutableType obj = new ImmutableType(def);
POOL.put(def, obj);
return obj;
}
}
}
Definition stores the state of the ImmutableType. If a type with the same definition already exists in the pool, then re-use it. Otherwise, create it, add it to the pool then return it as the value.
As for the statement about marking the class final, immutable types should not be extensible in the first place (to avoid possibly modifying behavior). Marking every method final is just crazy for immutable classes.

why is Immutable Objects safe in Double-Checked Locking?

At the about bottom of http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html, it says:
Double-Checked Locking Immutable Objects
If Helper is an immutable object, such that all of the fields of Helper are final, then double-checked locking will work without having to use volatile fields. The idea is that a reference to an immutable object (such as a String or an Integer) should behave in much the same way as an int or float; reading and writing references to immutable objects are atomic.
The sample and explanation of mutable one is as follows:
// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
synchronized(this) {
if (helper == null)
helper = new Helper();
}
return helper;
}
// other functions and members...
}
The first reason it doesn't work
The most obvious reason it doesn't work it that the writes that initialize the Helper object and the write to the helper field can be done or perceived out of order. Thus, a thread which invokes getHelper() could see a non-null reference to a helper object, but see the default values for fields of the helper object, rather than the values set in the constructor.
If the compiler inlines the call to the constructor, then the writes that initialize the object and the write to the helper field can be freely reordered if the compiler can prove that the constructor cannot throw an exception or perform synchronization.
Even if the compiler does not reorder those writes, on a multiprocessor the processor or the memory system may reorder those writes, as perceived by a thread running on another processor.
My question is: why immutable class does't have the problem? I cannot see any relation of the reorder with whether the class is mutable.
Thanks
The reason why the code is "broken" for usual objects is that helper could be non null but point to an object that has not been completely initialised yet as explained in your quote.
However if the Helper class is immutable, meaning that all its fields are final, the Java Memory Model guarantees that they are safely published even if the object is made available through a data race (which is the case in your example):
final fields also allow programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass references to the immutable object between threads. This can provide safety guarantees against misuse of an immutable class by incorrect or malicious code. final fields must be used correctly to provide a guarantee of immutability.
Immutable classes did have the problem. The part that you have quoted is true after changes to the Java Memory were made in JSR133.
Specifically the changes that affect immutable objects are related to some changes that were made to the final keyword. Checkout http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight.
The important part is:
The values for an object's final fields are set in its constructor. Assuming the object is constructed "correctly", once an object is constructed, the values assigned to the final fields in the constructor will be visible to all other threads without synchronization.

why fields should be final in immutable class?

Strategy for defining immutable class says that
all the fields should be final.
For ex:
private String name;
Why does it have to be final?
Since I am not giving setter methods for it? It can't be changed.
Thanks.
If you read
private final String name;
you know the field is immutable.
If you read
private String name;
you have to read the entire class to check it is not changed anywhere. This is means much more work for you.
You may remember now, having just written the class that you didn't add a setter, but after writing many more classes you read your own class six month later, you won't remember reliably.
Even if it is not changed now, someone (possibly yourself) could change it later by adding code. However, you might have made the assumption the value won't change.
In short, only make it non-final when you mean the value to change, and make it final when you didn't expect it to change. Don't leave it as a may be/may be not.
Now imagine you are used to being clear about which fields can be changed and which cannot. This saves you a lot of work when reading some else's code. But you discover that you are reading code which is not clear and non-final doesn't mean it was changed, it now means you have to check things, you wouldn't normally have to check which is one more headache in trying to understand some code you really don't need.
A simple example of how much harder it is to read code to determine if a field is effectively final.
public class A {
static class B {
private int x;
}
// some code
This all looks fine up to this point, no setters or even methods in B. So B.x is immutable right?
static class C {
public void update(B b, int x) {
b.x = x; // this really compiles
}
}
}
Oops no, you have to read the whole class file.
It is far better for you to make every field you can final (which should have been the default IMHO) when you write the code, rather than leaving it for someone to figure out later.
The main reason (IMHO) is that when field is final is guaranteed to be visible in other threads immediately after constructor is finished.
Keeping the field final emphasizes the fact that it cannot be changed anywhere else.
Self documenting code the the field should not be changed
Compiler will help you by giving error if you change the field somewhere else
So final helps in many ways for making object Immutable.
It's good practice to make immutable fields final, even on otherwise mutable objects.
Note that private fields of one object in fact CAN be accessed by other instances of the same class.
An object (class or instance) is immutable, if its internal state cannot be changed (reflection doesn't count).
Making a field final guarantees only that the value (if it's a primitive) or reference (for non-primitives) cannot be changed.
For non-primitives, this doesn't automatically mean that the referenced value is also immutable. Which means that if your final field references, for example, a list, one cannot exchange the list, but add/remove values from it, thus changing the state of the object.
For an object to be immutable:
The internal state must be determined upon construction and can never change
This means all fields that define the state must be final (you may have other helper fields which don't belong to the state, that's ok but rare).
This also means that all refernced objects must be immutable. Some objects such as String are already immutable, others such as collections can be wrapped to make them immutable (Collections.immutableList|Set|Collection|...)
Making primitive types final ensures immutability. However making non primitive objects final sometimes makes no sense since final object states can be mutated.As Greg points out this depends on the type of Object in question
As the example you showed, all properties are primitive hence final keword make sense.
One benifit of declaring a field final is that it allows compiler to detect attempts to change the field during refactoring. A class can be immutable even if its fields are not final.
JVM guarantees that final fields of a class will be initialized before any thread gets hold of the object. Without this guarantee, a reference to an object may be published, i.e. become visible, to another thread before all the fields of this object are initialized, due to reorderings or other optimizations. This could cause racy access to these fields.
This is why, when creating an immutable object, you should always make all its fields final, even if they are not accessible via getter methods.

making a class immutable in java

To make a class immutable what I can do is:
1)Make class final
2)do not provide setters
3)mark all variables as final
But if my class has another object of some other class then , somone can change value of that object
class MyClass{
final int a;
final OtherClass other
MyClass(int a ,OtherClass other){
this.a = a;
this.other = other;
}
int getA(){
return a;
}
OtherClass getOther(){
return other;
}
public static void main(String ags[]){
MyClass m = new Myclass(1,new OtherClass);
Other o = m.getOther();
o.setSomething(xyz) ; //This is the problem ,How to prevent this?
}
}
A) Make the OtherClass immutable as well
or
B) Don't allow direct access to the OtherClass object, instead providing only getters to act as a proxy.
Edit to add: You could make a deep copy of OtherClass and return a copy rather than the original, but that generally isn't the type of behavior you would expect in Java.
Immutability is best considered from the perspective of the API user. So your object API needs to satisfy the following two conditions:
No way for an external user to change the value of the object
A guarantee that any time the user reads or makes use of the object's value in the future, it will get the same result
Important note: It is in fact OK to have mutable data inside an immutable object as long as it behaves as an immutable object from the perspective of the API user. Consider java.lang.String for example: although it is generally considered as the definitive immutable class, it does in fact have a mutable internal field for caching the hashCode (not many people know this!).
So to address your question, if you wish to contain another (mutable) object inside an immutable object then you typically need to do one or more of the following:
Guarantee that nobody else can change the value of the mutable object. Typically this means ensuring that no-one else can have a reference to the mutable object, so this is only usually possible if you create the object yourself rather than accept a reference from outside.
Take a defensive deep copy of the mutable object, and don't hand out references to the new copy. Only allow operations that read the new copy in the public API. If you need to hand out a reference to this object, then you need to take another defensive copy (to avoid handing out a reference to the internal copy).
Use an immutable wrapper for the mutable object. Something like Collections.unmodifiableList. This is useful if you want to hand out a reference to the internal mutable object but don't want to run the risk of it being modified.
All of these solutions are a bit hacky - a better solution overall is to avoid the use of mutable objects within immutable objects. In the long run it's asking for trouble because sooner or later a mutable reference will leak out and you will have an extremely hard to find bug. You are better moving towards a full hierarchy of immutable objects (the approach taken by languages like Scala and Clojure)
I assume OtherClass (by the way you say Other once) is meant to be a class you don't control, or which has to have a setter.
If you can't remove getOther, change it to getOtherView and return a read-only view of other. There will be wrappers for all the get methods, but no set ones.
Return deep clones from your getters. You may find this to be no easy task.
All the objects referenced in the immutable class should be immutable, or at least be encapsulated as private and making sure that they are not modified (not inside the methods of your class and definitely not from the outside). For instance, if you have this situation:
public class MyImmutable {
private MutableClass mutableObject;
}
... You can not provide the getMutableObject() method, because doing so will open the door for outside modifications, like this:
myImmutable.getMutableObject().setSomeAttribute(newValue);
As a special case of the above, all collections and/or maps should be made immutable, with the ummodifiableXXX() methods in the Collections class.
you cannot (reasonably) stop that in java. if you don't have control over the other class, there are ways to effectively get immutable behavior, but it can be very expensive in practice. basically, you must always return a copy of that class in any public method return values. (the jdk actually has this problem with the TimeZone class).
But If my class has another object of some other class then , somone
can change value of that object...
Java objects are not primitive. If you mark a primitive as final, then its value cannot be changed once it is assigned. However, object contents cannot be final, only object references can be final. So you cannot make an object in this way.
One solution might be abandoning all setter/mutator methods those could change the particular fields of the object and encapsulating them in a way that you can only access them, not change them.
It is possible to create the immutable class in java by following ways
1.Don't Provide setter methods.
2.Make all fields are as final and private.
3.Make Class as final.

Categories