I was reading multi-threading in Java and I come across this
Local variables are thread safe in Java.
Since then I have been thinking How/Why local variables are thread safe.
Can somebody please let me know.
When you create a thread it will have its own call stack created. Two threads will have two stacks and one thread never shares its stack with other thread.
All local variables defined in your program will be allocated memory in stack (As Jatin commented, memory here means, reference-value for objects and value for primitive types) (Each method call by a thread creates a stack frame on its own stack). As soon as method execution is completed by this thread, stack frame will be removed.
There is great lecture by Stanford professor in youtube which may help you in understanding this concept.
Local variables are stored in each thread's own stack. That means that local variables are never shared between threads. That also means that all local primitive variables are thread safe.
public void someMethod(){
long threadSafeInt = 0;
threadSafeInt++;
}
Local references to objects are a bit different. The reference itself is not shared. The object referenced however, is not stored in each threads's local stack. All objects are stored in the shared heap. If an object created locally never escapes the method it was created in, it is thread safe. In fact you can also pass it on to other methods and objects as long as none of these methods or objects make the passed object available to other threads
Think of methods like definitions of functionality. When two threads run the same method, they are in no way way related. They will each create their own version of each local variable, and will be unable to interact with each other in any way.
If variables aren't local (like instance variables defined outside of a method at the class level), then they are attached to the instance (not to a single run of the method). In this case, two threads running the same method both see the one variable, and this isn't thread-safe.
Consider these two cases:
public class NotThreadsafe {
int x = 0;
public int incrementX() {
x++;
return x;
}
}
public class Threadsafe {
public int getTwoTimesTwo() {
int x = 1;
x++;
return x*x;
}
}
In the first, two threads running on the same instance of NotThreadsafe will see the same x. This could be dangerous, because the threads are trying to change x! In the second, two threads running on the same instance of Threadsafe will see totally different variables, and can't affect each other.
Each method invocation has its own local variables and, obviously, a method invocation happens in a single thread. A variable that is only updated by a single thread is inherently thread-safe.
However, keep a close eye on what exactly is meant by this: only the writes to the variable itself are thread-safe; calling methods on the object that it refers to is not inherently thread-safe. Same goes for directly updating object's variables.
In addition to the other answers such as Nambari's.
I'd like to point out that you can use a local variable in an anoymous type method:
This method could be called in other threads which could compromise threadsafety, so java forces all local variables used in anoymous types to be declared as final.
Consider this illegal code:
public void nonCompilableMethod() {
int i=0;
for(int t=0; t<100; t++)
{
new Thread(new Runnable() {
public void run() {
i++; //compile error, i must be final:
//Cannot refer to a non-final variable i inside an
//inner class defined in a different method
}
}).start();
}
}
If java did allow this (like C# does through "closures"), a local variable would no longer be threadsafe in all circumstances. In this case, the value of i at the end of all the threads is not guaranteed to be 100.
Thread will have its own stack. Two threads will have two stacks and one thread never shares its stack with other thread. Local variables are stored in each thread's own stack. That means that local variables are never shared between threads.
Basically Four Type Of Storage Are There in java to store Class Information and data:
Method Area,Heap,JAVA Stack,PC
so Method area and Heap is shared by all the threads but every thread is having its own JAVA Stack and PC and that is not shared by any other Threads.
Each method in java is as Stack frame. so, when one method is called by a thread that stack frame is loaded on its JAVA Stack.All the local variable which are there in that stack frame and related operand stack are not shared by others.
PC will have information of next instruction to execute in method's byte code.
so all the local variables are THREAD SAFE.
#Weston has also Given good answer.
Java thread safe of local variables
Only local variables are stored on the thread stack.
Local variable that is primitive type (e.g. int, long...) is stored on the thread stack and as a result - other thread does not have an access to it.
Local variable that is reference type (successor of Object) contains from 2 parts - address(which is stored on thread stack) and the object(which is stored on heap)
class MyRunnable implements Runnable() {
public void run() {
method1();
}
void method1() {
int intPrimitive = 1;
method2();
}
void method2() {
MyObject1 myObject1 = new MyObject1();
}
}
class MyObject1 {
MyObject2 myObject2 = new MyObject2();
}
class MyObject2 {
MyObject3 myObject3 = MyObject3.shared;
}
class MyObject3 {
static MyObject3 shared = new MyObject3();
boolean b = false;
}
[JVM Memory model]
Related
Assuming this class:
public class AmIThreadSafe {
private int a;
private int b;
AmIThreadSafe(int a, int b) {
this.a = a;
this.b = b;
}
}
Assuming that instance's reference to this class (declared as volatile) is accessible by some threads (leading to race condition) as soon as the this(reference) escapes:
volatile AmIThreadSafe instance = new AmIThreadSafe(1,2);
Here, I'm sure that the fact of assigning instance reference happens-before reading by threads.
But what about the AmIThreadSafe's fields?
Does the external volatile keyword also imply an happens-before relation concerning a and b fields?
Or is it rather possible to end up with any thread seeing stale values (default values 0 in this case since int) due to a potential statements reordering during constructor?
In other word, should I declare a and b final or volatile to prevent any surprises with the JMM or is just indicating volatile on the instance's reference enough?
----------------UPDATED POST - A GOOD ANSWER:----------------------------
The following article confirms by its sample that in my case, a and b are protected from JMM optimisations that prevent a permanent happens-before relation.
http://jeremymanson.blogspot.fr/2008/11/what-volatile-means-in-java.html
Declaring instance as volatile does not make its fields volatile, but if I understand your question correctly, then — yes, it's enough in your case.
Per §17.4.5 of the spec:
a volatile write in one thread happens-before any subsequent volatile read in another thread.
statements within the same thread have the happens-before relationship that you'd expect.
happens-before relationships are transitive.
So, if a thread perceives instance as having been initialized, then the initialization of instance happened-before it, and the initialization of instance's fields happened-before that, so the thread will perceive instance's fields as having been initialized.
No it's not enough to make it volatile. Thread safety depends on the usage though. E.g., this could still produce unexpected results if another thread is modifying the values.
assuming public variables for simplicity
volatile AmIThreadSafe instance = new AmIThreadSafe(1,2);
if (instance.x == 0) {
// instance.x might have changed between checking and assigning
instance.x = instance.x + 1;
}
volatile only applies to a variable (e.g., x and y are not automatically volatile just because instance is). This should be clear from JLS 8.3.1.4
The volatile in your case applies only to the reference of AmlThreadSafe. You still have to make the instance variables (a and b) volatile or access them in a synchronized block. Otherwise you can get stale data.
Yes.
thread 1 thread 2
1 write(a)
2 write(instance)
3 read(instance)
4 read(a)
Since instance is volatile, [2] happens-before [3].
Since happens-before is transitive, we have hb(1,2), hb(2,3), hb(3,4), therefore hb(1,4)
If a and b are only modified in the constructor, then in this case you should be fine because the object is created (and a and b set) BEFORE the reference is assigned to instance, and any other threads won't have locally-cached copies of the memory at those locations because it's a new object that the thread couldn't have seen before. In other words, I don't believe it's possible that another thread will ever be able to see the "default" value of 0 for a and b because the constructor will run completely before the object's reference is assigned to instance.
However if a and b can be modified after the constructor, then the other answers here are correct - you need synchronization around them.
If you are going to assume that a and b won't be modified outside of the constructor, then there's no reason not to make them final anyway, just to be safe.
Example :
class Something{
private volatile static Something instance = null;
private int x;
private int y;
private Something(){
this.x = 1;
this.y = 2;
}
public static Something getInstance() {
if (instance == null) {
synchronized (Something.class) {
if (instance == null)
instance = new Something();
}
}
}
return instance;
}
}
Explanation :
Lets say we have the above Code:
Now lets assume instance is not volatile for some time:
Thread#1 :
Comes in invoke getInstance method, Check for instance value{since null}, will go inside the IF condition, Access the Lock now again finds that instance == null, calls Something constructor. Now goes inside Constructor body.
As soon as Thread#1 goes inside Constructor body, Context Switch happens and now Thread #2 gets the turn to execute.
Thread#2 :
Invokes get Instance, But suddenly finds that instance is not null?Why{Reason will discuss just after this}and hence assign partially constructed Object to reference and returns it.
Now Situation is like this : Thread#1 Still needs to construct the Object Completely{needs to completely construct it} and Thread#2 got reference for partially constructed Object, and if it uses it like say reference.x //will print "x" Default Value and not "1"
Why partially constructed Object reference is returned in case Of Thread#2 ?
Reason is simple: Statements Reordering.
The Steps are simple for Object creation and reference association :
Allocate Memory in Heap.
Execute the Body of Constructor which will initialize class members.
Once above Step is completed, Reference to newly created Object.
But Sometimes Compiler can execute these Instructions out Of order, which means :
It might happen something like this :
Allocate Memory in Heap.
Reference to newly created Object.
Execute the Body of Constructor which will initialize class members.
Once the above two Steps happens and if Context Switching Happens, then reference will point to Object which is not initialized or it might be the case that Inside Constructor Body Context Switch happens then in that case reference will refer to partially initialized Object.
If such scenario occurs then reference will neither be null nor complete and hence it will break our Singleton motivation.
Now How Volatile will save our Life from such embarrassments :
As we know Volatile work with two principles : 1)Visibility 2)Happens Before Relationship.
Now Happens Before Relationship comes into Picture here.
So reference is volatile Write, so all statements should happen before any Volatile write.Again If we look at our Object construction steps:
Allocate memory for Object
Initialize member variables{Constructor Body}
Assign Object reference to volatile variable instance.
Step 3 has Volatile Variable write and as per Happens before .. All statements write guaranteed to be made available to step 3. And since it is volatile therefore No reordering will happen between volatile and non volatile statements, which was not the case in Old Java Memory Model.
So before executing Step 3, Step 1 and Step 2 are guaranteed to be happened and made available to Step 3. {In which order Step 1 and step 2 occurs we don't bother about it.}
So from this Thread will see either Completely created Object or null
As I am trying to get to grips with thread safety, I would like to know if this class is threadsafe? If two threads try to access its variables at any time it seems to me that it is thread safe because:
final variable is threadsafe by virtue of being immutable.
getter and setter are synchronized, so mObject can only be gotten, or set by one thread at a time. So there is no chance of two threads reading different values.
The method changeObj() is not synchronized but any block in it which deals with class variables (i.e. mObject) is synchronized.
Please tell me if I am wrong or if this class is not threadsafe.
public class MyClass{
private final String = "mystring"; //thread safe because final
private AnObject mObject;
public MyClass(){
//initialize
}
//only one class can set the object at a time.
public synchronized void setObj(AnObject a){
mObject = a;
}
//two threads trying to get the same object will not read different values.
public synchronized AnObject getObj(){
return mObject;
}
//better to synchronize the smallest possible block than the whole method, for performance.
public void changeObj(){
//just using local variables (on stack) so no need to worry about thread safety
int i = 1;
//i and j are just to simulate some local variable manipulations.
int j =3;
j+=i;
synchronized(this){
//change values is NOT synchronized. Does this matter? I don't think so.
mObject.changeValues();
}
}
}
No, it's not thread safe. You make sure only one thread can change the values in your AnObject at a time if it uses the changeObj() method, but you also provide a getter for this object, so any other thread could call changeValues() concurrently.
Your class in itself is thread safe in its current state (assuming any methods not shown here are), however you have one likely "bug" in your thinking;
mObject isn't 100% encapsulated, it is passed in through a setter and can be fetched through a getter. That means that any thread could get a reference to and call methods on the object referenced by mObject simultaneously without MyClass knowing about it.
In other words, AnObject's methods may need to be thread safe too.
At the very least, the synchronizing in MyClass doesn't in any way make mObject safe from threading problems.
Adding to Mr. JB Nizet's points, if AnObject.changeValues is a method that is designed to be overridden by clients, or calls such methods, then this, in the general case, opens the door for various unwanted behaviours, like deadlocks and data corruption. You must never cede control to alien code within a synchronized block. By "alien" I mean code not under your control. More details can be found in Effective Java, 2nd Ed, Item 67.
A final variable is not necessarily thread safe, only immutable final variables are thread safe -- that covers primitives and classes like String, or final variables of classes which themselves are thread-safe.
Your class is not thread safe because it exposes the variable a, but also requires it for its internal working.
The below example will demonstrate an example of how a could get into an inconsistent state.
Thread A
MyClass myClass = ...
myClass.changeObj();
// imagine Thread A is suspended during the synchronized block inside of
// changeObj()
Thead B
MyClass myClass = ...
AnObj anObj = myClass.getObj();
anObj.changeValues();
// uh-oh, I am modifying the state of this instance of anObj which is also
// currently being modified by Thread A
For MyClass to be truly thread safe you must do one of the following.
AnObj must also guarantee thread safety (by making methods that modify its state thread-safe)
AnObj must be immutable. That is, if you need to modify the state of AnObj you must create new instance of AnObj to hold the new state.
The getter for AnObj must not directly expose MyClass's instance of AnObj, but a rather return a copy of that instance.
I have a question about variable scope.
For example:
class A {
private static void test() {
// do something with local variables
}
}
Now I make two threads, and create one instance of A for each thread.
When I call test() in each thread, can I guarantee that test() is thread safe?
Where are the local varibles in test() stored? Each threads' stack? Heap space?
P.S. I know that static is totally pointless in this case. I found it in our legacy code; I just wanna make sure what I know!
Local variables are stored in each thread's own stack. That means that local variables are never shared between threads. That also means that all local primitive variables are thread safe.
Local references to objects are a bit different. The reference itself is not shared. The object referenced however, is not stored in each threads's local stack. All objects are stored in the shared heap. If an object created locally never escapes the method it was created in, it is thread safe. In fact you can also pass it on to other methods and objects as long as none of these methods or objects make the passed object available to other threads.
Object members are stored on the heap along with the object. Therefore, if two threads call a method on the same object instance and this method updates object members, the method is not thread safe.
Thread safety check: If a resource is created, used and disposed within the control of the same thread, and never escapes the control of this thread,the use of that resource is thread safe.
From: http://tutorials.jenkov.com/java-concurrency/thread-safety.html
When I call test() in each thread, can I guarantee that test() is thread safe?
Yes it would be thread safe if in test() method you are working on
method local variables.
Where are the local varibles in test() stored? each threads' stack? heap space?
Method Local variable are stored each thread's own stack.
For number 1, I don't know what test() does, so I cannot answer. If they modify some static variable of the class A, then it may not be thread safe. If both threads along the way are given reference to the same object, depending on how the object is defined, it might not be thread safe.
For number 2, local variables are in the stack of each thread (or at least conceptually like that), so there is no worry about the local variables being modified by the other threads.
I am reading Java Concurrency in Practice and kind of confused with the thread confinement concept. The book says that
When an object is confined to a thread, such usage is automatically thread-safe even if the confined object itself is not
So when an object is confined to a thread, no other thread can have access to it? Is that what it means to be confined to a thread? How does one keep an object confined to a thread?
Edit:
But what if I still want to share the object with another thread? Let's say that after thread A finishes with object O, thread B wants to access O. In this case, can O still be confined to B after A is done with it?
Using a local variable is one example for sure but that just means you don't share your object with other thread (AT ALL). In case of JDBC Connection pool, doesn't it pass one connection from one thread to another once a thread is done with that connection (totally clueless about this because I never used JDBC).
So when an object is confined to a thread, no other thread can have access to it?
No, it's the other way around: if you ensure that no other thread has access to an object, then that object is said to be confined to a single thread.
There's no language- or JVM-level mechanism that confines an object to a single thread. You simply have to ensure that no reference to the object escapes to a place that could be accessed by another thread. There are tools that help avoid leaking references, such as the ThreadLocal class, but nothing that ensures that no reference is leaked anywhere.
For example: if the only reference to an object is from a local variable, then the object is definitely confined to a single thread, as other threads can never access local variables.
Similarly, if the only reference to an object is from another object that has already been proven to be confined to a single thread, then that first object is confined to the same thread.
Ad Edit: In practice you can have an object that's only accessed by a single thread at a time during its lifetime, but for which that single thread changes (a JDBC Connection object from a connection pool is a good example).
Proving that such an object is only ever accessed by a single thread is much harder than proving it for an object that's confined to a single thread during its entire life, however.
And in my opinion those objects are never really "confined to a single thread" (which would imply a strong guarantee), but could be said to "be used by a single thread at a time only".
The most obvious example is use of thread local storage. See the example below:
class SomeClass {
// This map needs to be thread-safe
private static final Map<Thread,UnsafeStuff> map = new ConcurrentHashMap<>();
void calledByMultipleThreads(){
UnsafeStuff mystuff = map.get(Thread.currentThread());
if (mystuff == null){
map.put(Thread.currentThread(),new UnsafeStuff());
return;
}else{
mystuff.modifySomeStuff();
}
}
}
The UnsafeStuff objects itself "could be shared" with other threads in the sense that if you'd pass some other thread instead of Thread.currentThread() at runtime to the map's get method, you'd get objects belonging to other threads. But you are choosing not to. This is "usage that is confined to a thread". In other words, the runtime conditions are such that the objects is in effect never shared between different threads.
On the other hand, in the example below the object is automatically confined to a thread, and so to say, the "object itself" is confined to the thread. This is in the sense that it is impossible to obtain reference from other threads no matter what the runtime condition is:
class SomeClass {
void calledByMultipleThreads(){
UnsafeStuff mystuff = new UnsafeStuff();
mystuff.modifySomeStuff();
System.out.println(mystuff.toString());
}
}
Here, the UnsafeStuff is allocated within the method and goes out of scope when the method returns.. In other words, the Java spec is ensuring statically that the object is always confined to one thread. So, it is not the runtime condition or the way you use it that is ensuring the confinement, but more the Java spec.
In fact, modern JVM sometimes allocate such objects on stack, unlike the first example (haven't personally checked this, but I don't think at least current JVMs do).
Yet in other words, in the fist example the JVM can't be sure if the object is confined within a thread by just looking inside of calledByMultipleThreads() (who knows what other methods are messing with SomeClass.map). In the latter example, it can.
Edit: But what if I still want to
share the object with another thread?
Let's say that after thread A finishes
with object O, thread B wants to
access O. In this case, can O still be
confined to B after A is done with it?
I don't think it is called "confined" in this case. When you do this, you are just ensuring that an object is not accessed concurrently. This is how EJB concurrency works. You still have to "safely publish" the shared object in question to the threads.
So when an object is confined to a thread, no other thread can have access to it?
That's what thread confinement means - the object can only EVER be accessed by one thread.
Is that what it means to be confined to a thread?
See above.
How does one keep an object confined to a thread?
The general principle is to not put the reference somewhere that would allow another thread to see it. It is a little bit complicated to enumerate a set of rules that will ensure this, but (for instance) if
you create a new object, and
you never assign the object's reference to an instance or class variable, and
you never call a method that does this for the reference,
then the object will be thread confined.
I guess that's what want to say. Like creating a object inside the run method and not passing the reference to any other instance.
Simple example:
public String s;
public void run() {
StringBuilder sb = new StringBuilder();
sb.append("Hello ").append("world");
s = sb.toString();
}
The StringBuilder instance is thread-safe because it is confined to the thread (that executes this run method)
One way is "stack confinement" in which the object is a local variable confined to the thread's stack, so no other thread can access it. In the method below, the list is a local variable and doesn't escape from the method. The list doesn't have to be threadsafe because it is confined to the executing thread's stack. No other thread can modify it.
public String foo(Item i, Item j){
List<Item> list = new ArrayList<Item>();
list.add(i);
list.add(j);
return list.toString();
}
Another way of confining an object to a thread is through the use of a ThreadLocal variable which allows each thread to have its own copy. In the example below, each thread will have its own DateFormat object and so you don't need to worry about the fact that DateFormat is not thread-safe because it won't be accessed by multiple threads.
private static final ThreadLocal<DateFormat> df
= new ThreadLocal<DateFormat>(){
#Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd");
}
};
Further Reading
See: http://codeidol.com/java/java-concurrency/Sharing-Objects/Thread-Confinement/
A more formal means of maintaining
thread confinement is ThreadLocal,
which allows you to associate a
per-thread value with a value-holding
object. Thread-Local provides get and
set accessormethods that maintain a
separate copy of the value for each
thread that uses it, so a get returns
the most recent value passed to set
from the currently executing thread.
It holds a copy of object per one thread, thread A can't access copy of thread B and broke it's invariants if you will do it specially (for example, assign ThreadLocal value to static variable or expose it using other methods)
That's exactly what it means. The object itself is accessed by only one thread, and is thus thread-safe. ThreadLocal objects are a kind of objects that are bound to an only thread
I means that only code running in one thread accesses the object.
When this is the case, the object doesn't need to be "thread safe"
I'm confused by an issue about reference and synchronized keyword a long time.
I usually see some code like this:
Class someClass {
...
private SomeObject mObject;
...
public void someMethod() {
...
final SomeObject obj = mObject;
...
//then use the 'obj' variable rather than mObject
...
}
}
My question is why should use local final variable obj to replace the member variable?
Why not use the member variable directly?
I also see some example code associated with 'synchronized' keyword,like this:
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
Why these code can achieve the synchronized goal?
Thanks!
From what I can understand of your question and the first example, the code is trying to avoid threading problems by wanting to take a local copy of the member variable. The first example doesn't do this, it just gets a new local variable pointing to the same object the member variable points to, but doesn't actually protect invokations on that object from threading issues.
Edit following #Nick's comment: like Nick says, the first example's someMethod method avoids the possibility of having the mObject being replaced by another instance half way through. It doesn't however protect against threading issues by concurrent invokations on the same instance.
1>
I think for ur first question...member variable is not used directly because that reference object can be used in some other methods as well....and in other methods it may not be required to be declared as final as in case of the method as u have shown....so it is good practice to create a local reference of that variable.....
2>
Suppose some reference object is being accessed concurrently using threads....now if that object modifies some data then for concurrent access integrity of that data is lost....so it is required that there is some kind of lock on that object reference so that while one thread is accessing one of the reference of that object some other thread should not be able to access it....so this synchronized keyword is used to achieve just that...
In the first example, I believe the idea is to take a copy of the member variable in a final local variable so that if the member variable is changed on another thread, the copy in the member function will remain the same.
The second example is similar in that it's taking a copy of the currently connected thread in a local variable.
Imagine in either case if the member variable (or connected thread) were accessed directly and then changed part way through the function call by another thread, undefined behaviour may occur.
I'm sure there's a name for this coding pattern but I can't remember it!
As far as the first question is concerned it's making sure that the method can't modify the object, by aliasing it to a final variable you're ensuring you're not reassigning something later? I'm not sure...
The second question:
this works because if mState is not connected then we return from the method and r.write() doesn't get executed. It uses the object itself as a lock.