Java Immutable Objects [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am learning the concept of immutability.
I understand that immutable objects cannot change their values once the object is created.
But I didn't understand the following uses of immutable objects.
They are
are automatically thread-safe and have no synchronization issues. How ? Proof ?
do not need a copy constructor. How ? Any example ?
do not need an implementation of clone How ? Any example ?
do not need to be copied defensively when used as a field How ? Any example ?
always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object throws an exception, it's never left in an undesirable or indeterminate state. How ? Any example ?
Could someone please explain each of these points in detail with examples supporting it ?
Thanks.

..are automatically thread-safe and have no synchronization issues
Concurrency problems happen when two different threads modify the state of the same object. Immutable objects can't be modified, so no problems.
Example: A String. Two threads can be passed the same String without worry since neither can mutate it in any way.
do not need a copy constructor
... because copy is the only way to mutate it. One common design pattern for immutable objects for every "modification" operation to make a copy and then perform the operation on the new object.
Copy constructors are usually used on objects that you want to change without affecting the original. This is always the case (by definition) with immutable objects.
In the case of String, all the methods and the + operator return new Strings.
do not need an implementation of clone
see above.
do not need to be copied defensively when used as a field
Once upon a time I did something silly. I had a set of enums in a List:
private static final List<Status> validStatuses;
static {
validStatuses = new ArrayList<Status>();
validStates.add(Status.OPEN);
validStates.add(Status.REOPENED);
validStates.add(Status.CLOSED);
}
This list was returned from a method:
public static List<Status> getAllStatuses() {
return validStates;
}
I retrieved that list but only wanted to show the open states in the interface:
List<Status> statuses = Status.getAllStatuses();
statuses.remove(Status.CLOSED);
Great, it worked! Wait, now all status lists are showing only those two -- even after page refresh! What happened? I modified a static object. Oops.
I could have used defensive copying on the return object of getAllStatuses. Or, I could use something like Guava's ImmutableList in the first place:
private static final List<Status> validStatuses =
ImmutableList.of(Status.OPEN, Status.REOPENED, Status.CLOSED);
Then when I did something dumb:
List<Status> statuses = Status.getAllStatuses();
statuses.remove(Status.CLOSED); // Exception!
always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object throws an exception, it's never left in an undesirable or indeterminate state.
Because the class can never be modified, all states emitted by modification are whole, qualified objects (because they cannot change, they must always be in a qualified state to be useful). An exception would not emit a new object and therefore you can never have an undesirable or indeterminate state.

They are automatically thread-safe and have no synchronization issues
Yes due to the guarantees provided by the Java Memory Model for final fields:
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.
do not need to be copied defensively when used as a field How ? Any example ?
Because they are immutable, they can't be modified, so it is fine to share them with external code (you know they won't be able to mess up with the state of the object).
Corollary: you don't need to copy / clone immutable objects.
always have "failure atomicity"
An immutable object does not change once it is properly constructed. So either construction fails and you get an exception or it does not and you know the object is in a consistent state.

It's not a concept that can be usefully explained with examples of it. The advantage of immutable objects is that you know their data cannot change, so you don't have to worry about that. You can use your immutable object freely without having fear that the method in which you are passing them will change it.
when we are performing a multithreaded program than this comes handy because bugs based on the data changed by the threads is not supposed to be done

Automatically thread safe
because they cannot be changed (cannot mutate) - any thread accessing it finds the object in same state. So there are no situations like one thread changes state of object, then second thread takes over and changes state of object, then again first one takes over with no clue, that it was changed by someone else
good example is ArrayList - if one thread iterates through its' elements and second thread removes some of them, first thread then throws some kind of concurrency exception. With immutable list this is prevented
Copy constructor
it does not mean that it cannot have a copy constructor. It is a constructor to which you pass object of same type, and you create new object as a copy of given object. It is only a guess, but why would you copy object that is always in a same state?
public class A
{
private int a;
public A(int a)
{
this.a = a;
}
public A(A original)
{
this.a = original.a;
}
}
Implementation of clone
same issue, cloning object, that is always in same state usually only takes space in memory. But you can do it, if you want to create mutable object out of immutable
good example are again collections, you can generate mutable collection out of immutable
Defensive copying
defensive copy means, that when you are setting an object to a field, you create new object of same type which is copy of the original
Example

Related

Can ArrayList be used for readonly purpose in multithreaded environment?

I have few ArrayList<T> containing user defined objects (e.g. List<Student>, List<Teachers>). The objects are immutable in nature, i.e. no setters are provided - and also, due to the nature of the problem, "no one" will ever attempt to modify these objects. Once the 'ArrayList' is populated, no further addition/removal of objects is allowed/possible. So List will not dynamically change.
With such given condition, can this data structures (i.e. ArraList) be safely used by multiple threads (simultaneously)? Each of the thread will just read the object-properties, but there is no "set" operation possible.
So, my question is can I rely on ArrayList? If not, what other less expensive data structures can be used in such scenario?
You can share any objects or data structures between threads if they are never modified after a safe publication. As mentioned in the comments, there must be a * happen-before* relationship between the writes that initialize the ArrayList and the read by which the other threads acquire the reference.
E.g. if you setup the ArrayList completely before starting the other threads or before submitting the tasks working on the list to an ExecutorService you are safe.
If the threads are already running you have to use one of the thread safe mechanisms to hand-over the ArrayList reference to the other threads, e.g. by putting it on a BlockingQueue.
Even simplest forms like storing the reference into a static final or volatile field will work.
Keep in mind that your precondition of never modifying the object afterwards must always hold. It’s recommended to enforce that constraint by wrapping the list using Collections.unmodifiableList(…) and forget about the original list reference before publishing:
class Example {
public static final List<String> THREAD_SAFE_LIST;
static {
ArrayList<String> list=new ArrayList<>();
// do the setup
THREAD_SAFE_LIST=Collections.unmodifiableList(list);
}
}
or
class Example {
public static final List<String> THREAD_SAFE_LIST
=Collections.unmodifiableList(Arrays.asList("foo", "bar"));
}
Yes, you should be able to pass the array into each thread. There should be no access errors so long as the array is finished being written to before any thread is possibly getting the information.

Are final unmodifiable sets thread safe?

The javadocs are not clear about this: are unmodifiable sets thread safe? Or should I worry about internal state concurrency problems?
Set<String> originalSet = new HashSet<>();
originalSet.add("Will");
originalSet.add("this");
originalSet.add("be");
originalSet.add("thread");
originalSet.add("safe?");
final Set<String> unmodifiableSet = Collections.unmodifiableSet(originalSet);
originalSet = null; // no other references to the originalSet
// Can unmodifiableSet be shared among several threads?
I have stumbled upon a piece of code with a static, read-only Set being shared against multiple threads... The original author wrote something like this:
mySet = Collections.synchronizedSet(Collections.unmodifiableSet(originalSet));
And then every thread access it with code such as:
synchronized (mySet) {
// Iterate and read operations
}
By this logic only one thread can operate on the Set at once...
So my question is, for a unmodifiable set, when using operations such as for each, contains, size, etc, do I really need to synchronize access?
If it's an unmodifiable Set<String>, as per your example, then you're fine; because String objects are immutable. But if it's a set of something that's not immutable, you have to be careful about two threads both trying to change the same object inside the set.
You also have to be careful about whether there's a reference somewhere to the Set, that's not unmodifiable. It's possible for a variable to be unmodifiable, but still be referring to a Set which can be modified via a different variable; but your example seems to have that covered.
Objects that are "de facto" immutable are thread safe. i.e. objects that never change their state. That includes objects that could theoretically change but never do.
However all the objects contained inside must also be "de facto" immutable.
Furthermore the object only starts to become thread safe when you stop modifying it.
And it needs to be passed to the other threads in a safe manner. There are 2 ways to do that.
1.) you start the other threads only after you stopped modifying your object. In that case you don't need any synchronization at all.
2.) the other threads are already running while you are modifying the object, but once you completed constructing the object, you pass it to them through a synchronized mechanism e.g. a ConcurrentLinkedDeque. After that you don't need any further synchronization.

How to ensure thread safety of utility static method?

Is there any general way or rules exits by which we can ensure the thread safety of static methods specifically used in various Utility classes of any applications. Here I want to specifically point out the thread safety of Web Applications.
It is well know that static methods with Immutable Objects as parameters are thread safe and Mutable Objects are not.
If I have a utility method for some manipulation of java.util.Date and that method accepts an instance of java.util.Date, then this method would not be thread safe. Then how to make it thread safe without changing the way of parameter passing?
public class DateUtils {
public static Date getNormalizeDate(Date date) {
// some operations
}
}
Also is the class javax.faces.context.FacesContext mutable? Is it thread safe to pass an instance of this class to such static utility method?
This list of classes, instances of which can be or cannot be passed as parameters, could be long; so what points should we keep in mind while writing codes of such utility classes?
It is well known that static methods with immutable objects as parameters are thread safe and mutable objects are not.
I would contest this. Arguments passed to a method are stored on a stack, which is a per-thread idiom.
If your parameter is a mutable object such as a Date then you need to ensure other threads are not modifying it at the same time elsewhere. But that's a different matter unrelated to the thread-safety of your method.
The method you posted is thread-safe. It maintains no state and operates only on its arguments.
I would strongly recommend you read Java Concurrency in Practice, or a similar book dedicated to thread safety in Java. It's a complex subject that cannot be addressed appropriately through a few StackOverflow answers.
Since your class does not hold any member variables, your method is stateless (it only uses local variables and the argument) and therefore is thread safe.
The code that calls it might not be thread safe but that's another discussion. For example, Date not being thread safe, if the calling code reads a Date that has been written by another thread, you must use proper synchronization in the Date writing and reading code.
Given the structure of the JVM, local variables, method parameters, and return values are inherently "thread-safe." But instance variables and class variables will only be thread-safe if you design your class appropriately. more here
I see a lot of answers but none really pointing out the reason.
So this can be thought like this,
Whenever a thread is created, it is created with its own stack (I guess the size of the stack at the time of creation is ~2MB). So any execution that happens actually happens within the context of this thread stack.
Any variable that is created lives in the heap but it's reference lives in the stack with the exceptions being static variables which do not live in the thread stack.
Any function call you make is actually pushed onto the thread stack, be it static or non-static. Since the complete method was pushed onto the stack, any variable creation that takes place lives within the stack (again exceptions being static variables) and only accessible to one thread.
So all the methods are thread safe until they change the state of some static variable.
I would recommend creating a copy of that (mutable) object as soon as the method starts and use the copy instead of original parameter.
Something like this
public static Date getNormalizeDate(Date date) {
Date input = new Date(date.getTime());
// ...
}
Here's how I think of it: imagine a CampSite (that's a static method). As a camper, I can bring in a bunch of objects in my rucksack (that's arguments passed in on the stack). The CampSite provides me with a place to put my tent and my campstove, etc, but if the only thing the CampSite does is allow me to modify my own objects then it's threadsafe. The CampSite can even create things out of thin air (FirePit firepit = new FirePit();), which also get created on the stack.
At any time I can disappear with all my objects in my ruckstack and one of any other campers can appear, doing exactly what they were doing the last time they disappeared. Different threads in this CampSite will not have access to objects on the stack created CampSite in other threads.
Say there's only one campStove (a single object of CampStove, not separate instantiations). If by some stretch of the imagination I am sharing a CampStove object then there are multi-threading considerations. I don't want to turn on my campStove, disappear and then reappear after some other camper has turned it off - I would forever be checking if my hot dog was done and it never would be. You would have to put some synchronization somewhere... in the CampStove class, in the method that was calling the CampSite, or in the CampSite itself... but like Duncan Jones says, "that's a different matter".
Note that even if we were camping in separate instantiations of non-static CampSite objects, sharing a campStove would have the same multi-threading considerations.
We will take some examples to see if static method is Thread-Safe or not.
Example 1:
public static String concat (String st1, String str2) {
return str1 + str2
}
Now above method is Thread Safe.
Now we will see another example which is not thread-safe.
Example 2:
public static void concat(StringBuilder result, StringBuilder sb, StringBuilder sb1) {
result.append(sb);
result.append(sb1);
}
If you see both methods are very very primitive but still one is thread safe and other one is not. Why? What difference both having?
Are static methods in utilities prone to non thread-safe? Lot’s of questions right?
Now every thing depends on how you implement method & which type of objects you are using in your method. Are you using thread safe objects? Are these objects / classes are mutable?
If you see in Example 1 arguments of concat method are of type String which are immutable and passed by value so this method is completely thread-safe.
Now in Example 2 arguments are of StringBuilder type which are mutable so other thread can change value of StringBuilder which makes this method is potentially non thread-safe.
Again this is not completely true. If you are calling this utility method with local variables then you never having any problem related to thread-safety. Because each thread uses it’s own copy for local variables so you never run into any thread safety issues. But that is beyond scope of above static method. It’s depend on calling function / program.
Now static methods in utility class are kind of normal practice. So how we can avoid it? If you see Example 2 I am modifying 1st parameter. Now if you want to make this method really thread safe then one simple thing you can do. Either use non-mutable variables / objects or do not change / modify any method parameters.
In Example 2 we already used StringBuilder which is mutable so you can change implementation to make static method thread safe as follows:
public static String concat1(StringBuilder sb, StringBuilder sb1) {
StringBuilder result = new StringBuilder();
result.append(sb);
result.append(sb1);
return result.toString();
}
Again going to basics always remember if you are using immutable objects & local variables then you are miles away from thread safety issues.
From the arcticle(https://nikhilsidhaye.wordpress.com/2016/07/29/is-static-method-in-util-class-threadsafe/)Thank you Nikhil Sidhaye for this simple article

Usefulness of immutable objects when the state of a program constantly changes

I know that immutable objects always have the same state, the state in which they are actually created. Their invariants are establised by the constructor and since their state does not change after construction , those invariants always hold good and this is why they are safe to publish in a multi threaded environment. This is all fine but since we live in a dynamic world , where the state of program changes continuously , what benefits do such objects give us if we construct the state of our program through immutable objects?
"what benefits do such objects give us" you already answered that.
Regarding the "dynamic" part of your question, if you need to "change" an immutable object, you can create a new one from the old one:
Immutable oldObj = new Immutable(...);
Immutable newObj = new Immutable(oldObj.property1, "a new value for property 2");
If you find that you keep doing that repeatedly, then maybe you need to make the object mutable and add the relevant tread-safety features that are needed to be able to use that object in a concurrent environment.
Immutable objects allow you to cleanly communicate changes of state to different threads.
It is a good practice to use immutable objects to represent messages exchanged between threads. Once such message is sent, its payload can not be altered, which prevents many concurrency related bugs. If a thread needs to communicate some further changes, it just sends next messages.
Immutable objects are very helpful when you need some static object whose state never changes .Greatest advantage are immutability , object semantics and smart pointers renders object ownership a moot point. Implicitly this also means deterministic behaviour in the presence of concurrency.
Java has already defined some Immutable classes like String Integer.
Other benefit is they always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object throws an exception, it's never left in an undesirable or indeterminate state .
Let say if you have a global cache of static objects like country codes , here you can apply Immutability.
Why do we need immutable class?
Immutable objects are really useful in cases like this, with a String object:
public class A {
private volatile String currentName = "The First Name";
public String getCurrentName() {
// Fast: no synching or blocking! Can be called billions of times by
// billions of threads with no trouble.
// (Does need to be read from memory always because it's volatile.)
return currentName;
}
public whatever someMethod() {
... code ...
// Simple assignment in this case. Could involve synchronization
// and lots of calculations, but it's called a lot less than
// getCurrentName().
currentName = newName;
... code ...
}
}
public class B {
... in some method ...
A objA = something;
// Gets "name" fast despite a billion other threads doing the same thing.
String name = objA.getCurrentName();
// From this point on, String referenced by "name" won't change
// regardless of how many times A.currentName changes.
... code with frequent references to objA
}
This allows complex data (or even simple data, this case) that must be consistent (if not precisely up-to-date) to be updated and delivered to anybody who wants it very quickly and in a thread-safe manner. The data delivered will soon become outdated, perhaps, but it will keep its value during the calling method and remain consistent.

Immutable objects are thread safe, but why?

Lets say for example, a thread is creating and populating the reference variable of an immutable class by creating its object and another thread kicks in before the first one completes and creates another object of the immutable class, won't the immutable class usage be thread unsafe?
Creating an immutable object also means that all fields has to be marked as final.
it may be necessary to ensure correct behavior if a reference to
a newly created instance is passed from one thread to another without
synchronization
Are they trying to say that the other thread may re-point the reference variable to some other object of the immutable class and that way the threads will be pointing to different objects leaving the state inconsistent?
Actually immutable objects are always thread-safe, but its references may not be.
Confused?? you shouldn't be:-
Going back to basic:
Thread-safe simply means that two or more threads must work in coordination on the shared resource or object. They shouldn't over-ride the changes done by any other thread.
Now String is an immutable class, whenever a thread tries to change it, it simply end up creating a new object. So simply even the same thread can't make any changes to the original object & talking about the other thread would be like going to Sun but the catch here is that generally we use the same old reference to point that newly created object.
When we do code, we evaluate any change in object with the reference only.
Statement 1:
String str = "123"; // initially string shared to two threads
Statement 2:
str = str+"FirstThread"; // to be executed by thread one
Statement 3:
str=str+"SecondThread"; // to be executed by thread two
Now since there is no synchronize, volatile or final keywords to tell compiler to skip using its intelligence for optimization (any reordering or caching things), this code can be run in following manner.
Load Statement2, so str = "123"+"FirstThread"
Load Statement3, so str = "123"+"SecondThread"
Store Statement3, so str = "123SecondThread"
Store Statement2, so str = "123FirstThread"
and finally the value in reference str="123FirstThread" and for sometime if we assume that luckily our GC thread is sleeping, that our immutable objects still exist untouched in our string pool.
So, Immutable objects are always thread-safe, but their references may not be. To make their references thread-safe, we may need to access them from synchronized blocks/methods.
In addition to other answers posted already, immutable objects once created, they cannot be modified further. Hence they are essentially read-only.
And as we all know, read-only things are always thread-safe. Even in databases, multiple queries can read same rows simultaneously, but if you want to modify something, you need exclusive lock for that.
Immutable objects are thread safe, but why?
An immutable object is an object that is no longer modified once it has been constructed. If in addition, the immutable object is only made accessible to other thread after it has been constructed, and this is done using proper synchronization, all threads will see the same valid state of the object.
If one thread is creating populating the reference variable of the immutable class by creating its object and at the second time the other thread kicks in before the first thread completes and creates another object of the immutable class, won't the immutable class usage be thread unsafe?
No. What makes you think so? An object's thread safety is completely unaffected by what you do to other objects of the same class.
Are they trying to say that the other thread may re-point the reference variable to some other object of the immutable class and that way the threads will be pointing to different objects leaving the state inconsistent?
They are trying to say that whenever you pass something from one thread to another, even if it is just a reference to an immutable object, you need to synchronize the threads. (For instance, if you pass the reference from one thread to another by storing it in an object or a static field, that object or field is accessed by several threads, and must be thread-safe)
Thread safety is data sharing safety, And because in your code you make decisions based on the data your objects hold, the integrity and deterministic behaviour of it is vital. i.e
Imagine we have a shared boolean instance variable across two threads that are about to execute a method with the following logic
If flag is false, then I print "false" and then I set the flag back to true.
If flag is true, then I print "true" and then I set the flag back to false.
If you run continuously in a single thread loop, you will have a deterministic output which will look like:
false - true - false - true - false - true - false ...
But, if you ran the same code with two threads, then, the output of your output is not deterministic anymore, the reason is that the thread A can wake up, read the flag, see that is false, but before it can do anything, thread B wakes up and reads the flag, which is also false!! So both will print false... And this is only one problematic scenario I can think of... As you can see, this is bad.
If you take out the updates of the equation the problem is gone, just because you are eliminating all the risks associated with data sync. that's why we say that immutable objects are thread safe.
It is important to note though, that immutable objects are not always the solution, you may have a case of data that you need to share among different threads, in this cases there are many techniques that go beyond the plain synchronization and that can make a whole lot of difference in the performance of your application, but this is a complete different subject.
Immutable objects are important to guarantee that the areas of the application that we are sure that don't need to be updated, are not updated, so we know for sure that we are not going to have multithreading issues
You probably might be interested in taking a look at a couple of books:
This is the most popular: http://www.amazon.co.uk/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/ref=sr_1_1?ie=UTF8&qid=1329352696&sr=8-1
But I personally prefer this one: http://www.amazon.co.uk/Concurrency-State-Models-Java-Programs/dp/0470093552/ref=sr_1_3?ie=UTF8&qid=1329352696&sr=8-3
Be aware that multithreading is probably the trickiest aspect of any application!
Immutability doesn't imply thread safety.In the sense, the reference to an immutable object can be altered, even after it is created.
//No setters provided
class ImmutableValue
{
private final int value = 0;
public ImmutableValue(int value)
{
this.value = value;
}
public int getValue()
{
return value;
}
}
public class ImmutableValueUser{
private ImmutableValue currentValue = null;//currentValue reference can be changed even after the referred underlying ImmutableValue object has been constructed.
public ImmutableValue getValue(){
return currentValue;
}
public void setValue(ImmutableValue newValue){
this.currentValue = newValue;
}
}
Two threads will not be creating the same object, so no problem there.
With regards to 'it may be necessary to ensure...', what they are saying is that if you DON'T make all fields final, you will have to ensure correct behavior yourself.

Categories

Resources