Currently I'm reading "Java concurrency in practice", which contains this sentence:
Since the action of a thread accessing a stateless object can't affect the correctness of operations on other threads, stateless objects are thread-safe.
So, what is stateless object?
Stateless object is an instance of a class without instance fields (instance variables). The class may have fields, but they are compile-time constants (static final).
A very much related term is immutable. Immutable objects may have state, but it does not change when a method is invoked (method invocations do not assign new values to fields). These objects are also thread-safe.
If the object doesn't have any instance fields, it it stateless. Also it can be stateless if it has some fields, but their values are known and don't change.
This is a stateless object:
class Stateless {
void test() {
System.out.println("Test!");
}
}
This is also a stateless object:
class Stateless {
//No static modifier because we're talking about the object itself
final String TEST = "Test!";
void test() {
System.out.println(TEST);
}
}
This object has state, so it is not stateless. However, it has its state set only once, and it doesn't change later, this type of objects is called immutable:
class Immutable {
final String testString;
Immutable(String testString) {
this.testString = testString;
}
void test() {
System.out.println(testString);
}
}
The concept of stateless object is highly coupled with concept of side effects.
Shortly, that is the object that has no fields underneath which could have different values, dependently on different order of method calls.
In simple terms state of object means value of internal variables in that object.
Stateful - state of object can be changed, means internal values off member variables of that object can be changed
How values can be changed?
By setting the value.
When can you set that value?
When the variable is not final..
So, to make the class stateless, make the variable final, so that the value of that variable can't be changed neither in setter not in another method. It can be used only for computing.
An object without state, like instance variables that can change and vary depending on what has already happened to the object
Stateless: it has no fields and references no fields from other classes.
The state for a particular computation exists solely in local variables that are stored on the thread’s stack and are accessible only to the executing thread.
One thread accessing a method/class cannot influence the result of another thread accessing the same method/class; because the two threads do not share state, it is as if they were accessing different instances.
Since the actions of a thread accessing a stateless object cannot
affect the correctness of operations in other threads, Stateless objects are threadsafe.
A stateless object is an object that doesn't have any internal state (internal variable)
Just a clarification.
You can consider your class as stateless in the way that is stated before, even when it has an instance variable as far as this variable is final AND immutable.
If the instance variable is just final but mutable, a List of Strings in example, yes the variable's reference can not be changed but the contents of the List and thus the state of the class can be changed.
If you can not change any parameter or value etc. of an object, after its creation, then that object is thread-safe.
An objects that have absolutely no state then there is no problem with reusing them
at this point the question is: if they have absolutely no state why not make all the methods static and never create one at all?
Related
Goetz's Java Concurrency in Practice, page 41, mentions how this reference can escape during construction. A "don't do this" example:
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
Here this is "escaping" via the fact that doSomething(e) refers to the enclosing ThisEscape instance. The situation can be fixed by using static factory methods (first construct the plain object, then register the listener) instead of public constructors (doing all the work). The book goes on:
Publishing an object from within its constructor can publish an incompletely constructed object. This is true even if the publication is the last statement in the constructor. If the this reference escapes during construction, the object is considered not properly constructed.
I don't quite get this. If the publication is the last statement in the constructor, hasn't all the constructing work been done before that? How come is this not valid by then? Apparently there's some voodoo going on after that, but what?
The end of a constructor is a special place in terms of concurrency, with respect to final fields. From section 17.5 of the Java Language Specification:
An object is considered to be
completely initialized when its
constructor finishes. 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 usage model for final fields is a
simple one. Set the final fields for
an object in that object's
constructor. Do not write a reference
to the object being constructed in a
place where another thread can see it
before the object's constructor is
finished. If this is followed, then
when the object is seen by another
thread, that thread will always see
the correctly constructed version of
that object's final fields. It will
also see versions of any object or
array referenced by those final fields
that are at least as up-to-date as the
final fields are.
In other words, your listener could end up seeing final fields with their default values if it examines the object in another thread. This wouldn't happen if listener registration happened after the constructor has completed.
In terms of what's going on, I suspect there's an implicit memory barrier at the very end of a constructor, making sure that all threads "see" the new data; without that memory barrier having been applied, there could be problems.
Another problem arises when you subclass ThisEscape, and the child class invokes this consructor. The implicit this reference in the EventListener would have an incompletely constructed object.
There is a small but finite time between the registerListener ending and the constructor returning. Another thread could use come in at that time and attempt to call doSomething(). If the runtime didn't return straight to your code at that time, the object could be in a invalid state.
I'm not sure of java really but one example I can think of is where possibly the runtime relocates the instance before returning to you.
Its a small chance I grant you.
If I have a class like that:
public class MyObject {
private int myField = 2;
public void setMyField(int f) {
this.myField = f;
}
}
Will objects of this class be mutable?
Thanks!
Of course - if you want it to be immutable, then you need something like:
public class MyObject {
private final int myField;
public MyObject(int f) {
myfield = f;
}
public int getMyField() {
return myField;
}
}
yes
Mutable objects have fields that can be changed, immutable objects
have no fields that can be changed after the object is created.
You already have several answers with a "Yes".
I would like to add a "but" (if I would be bold, I would say "No" ;-)
Yes, an object of this class appears to be mutable, since it provides a setter to change the field. However, since it does not have a getter for that field, neither any other getter depending on that field, and since the field is private, it is currently not possible to read that state.
Put differently: The object has state, but it does not expose any state to the outside.
I would call that object "effectively immutable".
There are some design patterns, where objects are "effectively immutable", for example "Lazy Initialization" of an "Immutable Object".
Note: The concept of being "effectively immutable" is discussed in Section 3.5.4 of Java Concurrency in Practice by Brian Goetz.
Yes, objects of this class are mutable. The designer of the class can't prohibit by any technical means (in real existing Java) consumers of the objects to observe and modify the contents of the field.
private is an explicitly declared contract regarding intended usage of the field - this contract can be broken, e.g. with reflection.
Not providing any methods that change the data of an object after creation can also be a (implicitly declared) contract about intended use and mutability - this contract, too, can be broken, like any contract that needs two conforming parties.
Edit: Unless there is another party that has the means to enforce - like in Java the SecurityManager stopping you from changing a final field at runtime.
Yes, your object is mutable as the value of myField can be changed after the instance is created using the setter.
Immutability can be achieved using final fields, as it will not allow you to change the value of a variable once it is initialized.
Answer by #JakubK points out how you can make your class Immutable.
But declaring reference final wont make the object being pointed by it final.
For example:
class MyObject{
private final List<Integer> list = new ArrayList<Integer>();
public List<Integer> getList(){
return list;
}
}
I can change add a new element to the list from outside by doing something like this
instance.getList().add(1); //mutates the list
This example is not immutable, as the List can be changed by someone else.
To define whether something is mutable, one has to define what state is encapsulated thereby. If MyObject specifies that its state includes the value which Reflection will report for myField, then it is mutable. If that field is not specified as being part of the object's observable state, then it may be most purposes regarded as immutable.
To be more specific, I would regard a class as being immutable only if one could perform any combination of documented operations upon the class, in any sequence and with any timing (even on multiple threads), and not have any documented behavioral aspects of of any of them affected by any other. The fact that a method might change the contents of a private field is relevant if and only if that change would affect some documented behavioral aspect of another method call (to the same or different method). For example, I would say that the fact that String.hashCode() modifies the hash field does not make String mutable, because the value returned by hashCode() is not affected by whether or not the field had been written previously. If a class had a hashCode method which would, if a field was blank, generate a random number and store it in that field, and otherwise return the value directly, such a class would be mutable unless it ensured that the field was tested and set as an atomic operation. In the absence of such assurance, it would be possible for near-simultaneous calls to hashCode() to yield different values, and thus for future calls to differ values that would differ from at least one of them (implying that the object's state had changed between the call that returned the odd-ball value and the later call).
I would like to known if each instance of a class has its own copy of the methods in that class?
Lets say, I have following class MyClass:
public MyClass {
private String s1;
private String s2;
private String method1(String s1){
...
}
private String method2(String s2){
...
}
}
So if two differents users make an instance of MyClass like:
MyClass instanceOfUser1 = new MyClass();
MyClass instanceOfUser2 = new MyClass();
Does know each user have in his thread a copy of the methods of MyClass? If yes, the instance variables are then thread-safe, as long as only the instance methods manipulate them, right?
I am asking this question because I often read that instance variables are not thread-safe. And I can not see why it should be like that, when each user gets an instance by calling the new operator?
Each object gets its own copy of the class's instance variables - it's static variables that are shared between all instances of a class. The reason that instance variables are not necessarily thread-safe is that they might be simultaneously modified by multiple threads calling unsynchronized instance methods.
class Example {
private int instanceVariable = 0;
public void increment() {
instanceVariable++;
}
}
Now if two different threads call increment at the same then you've got a data race - instanceVariable might increment by 1 or 2 at the end of the two methods returning. You could eliminate this data race by adding the synchronized keyword to increment, or using an AtomicInteger instead of an int, etc, but the point is that just because each object gets its own copy of the class's instance variables does not necessarily mean that the variables are accessed in a thread-safe manner - this depends on the class's methods. (The exception is final immutable variables, which can't be accessed in a thread-unsafe manner, short of something goofy like a serialization hack.)
Issues with multi-threading arise primarily with static variables and instances of a class being accessed at the same time.
You shouldn't worry about methods in the class but more about the fields (meaning scoped at the class level). If multiple references to an instance of a class exist, different execution paths may attempt to access the instance at the same time, causing unintended consequences such as race conditions.
A class is basically a blueprint for making an instance of an object. When the object is instantiated it receives a spot in memory that is accessed by a reference. If more than one thread has a handle to this reference it can cause occurrences where the instance is accessed simultaneously, this will cause fields to be manipulated by both threads.
'Instance Variables are not thread safe' - this statement depends on the context.
It is true, if for example you are talking about Servlets. It is because, Servlets create only one instance and multiple threads access it. So in that case Instance Variables are not thread safe.
In the above simplified case, if you are creating new instance for each thread, then your instance variables are thread safe.
Hope this answers your question
A method is nothing but a set of instructions. Whichever thread calls the method, get a copy of those instructions. After that the execution begins. The method may use local variables which are method and thread-scoped, or it may use shared resources, like static resources, shared objects or other resources, which are visible across threads.
Each instance has its own set of instance variables. How would you detect whether every instance had a distinct "copy" of the methods? Wouldn't the difference be visible only by examining the state of the instance variables?
In fact, no, there is only one copy of the method, meaning the set of instructions executed when the method is invoked. But, when executing, an instance method can refer to the instance on which it's being invoked with the reserved identifier this. The this identifier refers to the current instance. If you don't qualify an instance variable (or method) with something else, this is implied.
For example,
final class Example {
private boolean flag;
public void setFlag(boolean value) {
this.flag = value;
}
public void setAnotherFlag(Example friend) {
friend.flag = this.flag;
}
}
There's only one copy of the bytes that make up the VM instructions for the setFlag() and setAnotherFlag() methods. But when they are invoked, this is set to the instance upon which the invocation occurred. Because this is implied for an unqualified variable, you could delete all the references to this in the example, and it would still function exactly the same.
However, if a variable is qualified, like friend.flag above, the variables of another instance can be referenced. This is how you can get into trouble in a multi-threaded program. But, as long as an object doesn't "escape" from one thread to be visible to others, there's nothing to worry about.
There are many situations in which an instance may be accessible from multiple classes. For example, if your instance is a static variable in another class, then all threads would share that instance, and you can get into big trouble that way. That's just the first way that pops into my mind...
In class we usually declare global variables and local variables. I have most of the time seen declaring global variables, setters ,getters. Are these essential everytime?Is it ok if I can implement it without using those things?
Generally you should always try to reduce the scope of visibility of variables, methods, classes etc.
So, if you need some variable that is used in one call sequence use local variable and method arguments to pass its value from method to method.
For example I have 2 methods foo() and bar() while foo calls bar:
public void foo() {
bar();
}
private void bar() {
}
Let's say both work on the same string appending to it some suffixes. You can use local variable as in the following example:
public String foo(String s) {
s += "foo1"
bar(s);
s += "foo2"
return s;
}
private String bar(String s) {
s += "bar1"
return s;
}
Or class level variable:
private String s;
public String foo() {
s += "foo1"
bar();
s += "foo2"
return s;
}
private String bar() {
s += "bar1"
return s;
}
The first way is better because:
it is encapsulated. No-one knows the detail of implementation. No-one can affect it from outside.
It is easier readable: you do not have to travel back and forward into your code to understand what objects participate in the implementation.
It is thread-safe without any extra efforts like synchronized blocks or atomic variable because it never uses object level variables.
The second implementation is not encapsulated: one can add code that changes the object state and affects on the next call of foo(). You have to go back and forward in you class to understand both algorithm and what variables are affected by algorithm. It is not thread-safe. Two concurrent threads running the same code may compete on changing the same variable.
I'm guessing that you are defining "global variable" as a member field variable (defined outside the context of a method). It is best to use the mutators (setters) and accessors (getters) when using member fields to allow you to change your implementation easier. One good example would be that if you are checking for conditions around a field when you get or set the variable state you can encapsulate the change in one location rather than spread across each time you use it.
By global variables you mean class member fields? If variable is only used within the scope of a method, then it should be local. If variable is essentially carrying any state information for the whole class instance - it should be declared as class member field (with setters and getters - if it's required to give access to these fields to other classes).
Good summary on Java classes is here: http://docs.oracle.com/javase/tutorial/java/javaOO/summaryclasses.html
There is no global variable in Java.
A field should only exist if it is a property of the object. It should not be used, for example, to store intermediate results between two method calls of the object.
Getters should only be defined if the outside world needs to access the information. If it doesn't need to, don't define a getter. The more private state is, the best it is because it allows the class to eveolve without impacting the other classes.
A setter should only be modified if the modification of the field is needed, and if it makes sense to modify this field in isolation to the other ones.
Good rules:
Less state is better than more state
Immutable state is better than mutable state
A method should always bring an object from a stable consistent state to another stable consistent state.
Goetz's Java Concurrency in Practice, page 41, mentions how this reference can escape during construction. A "don't do this" example:
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
Here this is "escaping" via the fact that doSomething(e) refers to the enclosing ThisEscape instance. The situation can be fixed by using static factory methods (first construct the plain object, then register the listener) instead of public constructors (doing all the work). The book goes on:
Publishing an object from within its constructor can publish an incompletely constructed object. This is true even if the publication is the last statement in the constructor. If the this reference escapes during construction, the object is considered not properly constructed.
I don't quite get this. If the publication is the last statement in the constructor, hasn't all the constructing work been done before that? How come is this not valid by then? Apparently there's some voodoo going on after that, but what?
The end of a constructor is a special place in terms of concurrency, with respect to final fields. From section 17.5 of the Java Language Specification:
An object is considered to be
completely initialized when its
constructor finishes. 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 usage model for final fields is a
simple one. Set the final fields for
an object in that object's
constructor. Do not write a reference
to the object being constructed in a
place where another thread can see it
before the object's constructor is
finished. If this is followed, then
when the object is seen by another
thread, that thread will always see
the correctly constructed version of
that object's final fields. It will
also see versions of any object or
array referenced by those final fields
that are at least as up-to-date as the
final fields are.
In other words, your listener could end up seeing final fields with their default values if it examines the object in another thread. This wouldn't happen if listener registration happened after the constructor has completed.
In terms of what's going on, I suspect there's an implicit memory barrier at the very end of a constructor, making sure that all threads "see" the new data; without that memory barrier having been applied, there could be problems.
Another problem arises when you subclass ThisEscape, and the child class invokes this consructor. The implicit this reference in the EventListener would have an incompletely constructed object.
There is a small but finite time between the registerListener ending and the constructor returning. Another thread could use come in at that time and attempt to call doSomething(). If the runtime didn't return straight to your code at that time, the object could be in a invalid state.
I'm not sure of java really but one example I can think of is where possibly the runtime relocates the instance before returning to you.
Its a small chance I grant you.