Local variables in static method and thread safety - java

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.

Related

How a thread can see stale reference of safely initialized object

I have been trying to figure out that how immutable objects which are safely published could be observed with stale reference.
public final class Helper {
private final int n;
public Helper(int n) {
this.n = n;
}
}
class Foo {
private Helper helper;
public Helper getHelper() {
return helper;
}
public void setHelper(int num) {
helper = new Helper(num);
}
}
So far I could understand that Helper is immutable and can be safely published. A reading thread either reads null or fully initialized Helper object as it won't be available until fully constructed. The solution is to put volatile in Foo class which I don't understand.
The fact that you are publishing a reference to an immutable object is irrelevant here.
If you are reading the value of a reference from multiple threads, you need to ensure that the write happens before a read if you care about all threads using the most up-to-date value.
Happens before is a precisely-defined term in the language spec, specifically the part about the Java Memory Model, which allows threads to make optimisations for example by not always updating things in main memory (which is slow), instead holding them in their local cache (which is much faster, but can lead to threads holding different values for the "same" variable). Happens-before is a relation that helps you to reason about how multiple threads interact when using these optimisations.
Unless you actually create a happens-before relationship, there is no guarantee that you will see the most recent value. In the code you have shown, there is no such relationship between writes and reads of helper, so your threads are not guaranteed to see "new" values of helper. They might, but they likely won't.
The easiest way to make sure that the write happens before the read would be to make the helper member variable final: the writes to values of final fields are guaranteed to happen before the end of the constructor, so all threads always see the correct value of the field (provided this wasn't leaked in the constructor).
Making it final isn't an option here, apparently, because you have a setter. So you have to employ some other mechanism.
Taking the code at face value, the simplest option would be to use a (final) AtomicInteger instead of the Helper class: writes to AtomicInteger are guaranteed to happen before subsequent reads. But I guess your actual helper class is probably more complicated.
So, you have to create that happens-before relationship yourself. Three mechanisms for this are:
Using AtomicReference<Helper>: this has similar semantics to AtomicInteger, but allows you to store a reference-typed value. (Thanks for pointing this out, #Thilo).
Making the field volatile: this guarantees visibility of the most recently-written value, because it causes writes to flush to main memory (as opposed to reading from a thread's cache), and reads to read from main memory. It effectively stops the JVM making this particular optimization.
Accessing the field in a synchronized block. The easiest thing to do would be to make the getter and setter methods synchronized. Significantly, you should not synchronize on helper, since this field is being changed.
Cite from Volatile vs Static in Java
This means that if two threads update a variable of the same Object concurrently, and the variable is not declared volatile, there could be a case in which one of the thread has in cache an old value.
Given your code, the following can happen:
Thread 1 calls getHelper() and gets null
Thread 2 calls getHelper() and gets null
Thread 1 calls setHelper(42)
Thread 2 calls setHelper(24)
And in this case your trouble starts regarding which Helper object will be used in which thread. The keyword volatile will at least solve the caching problem.
The variable helper is being read by multiple threads simultaneously. At the least, you have to make it volatile or the compiler will begin caching it in registers local to threads and any updates to the variable may not reflect in the main memory. Using volatile, when a thread starts reading a shared variable, it will clear its cache and fetch a fresh value from the global memory. When it finishes reading it, it will flush the contents of its cache into the main memory so that other threads may get the updated value.

Does "local variables are thread safe" come with a condition?

In another thread I came across this question, so I have to put it here as a simple and focused question.
void method(){
Machine machine = new Machine();
...
}
class Machine{
private static Tool tool = new Tool();
...
}
Although Machine is a local variable in method(), it's still thread unsafe because Machine has a static instance variable 'tool' that could be potentially thread unsafe, since all threads will share this 'tool' object due to static.
So if Machine is thread safe by itself through whatever way, then it can be safely stated that "the local variable machine" is thread safe. Otherwise, it's not safe, even though 'machine' is a local variable.
Is this understanding correct?
Yes, this understanding is correct. Only the variable itself is thread-safe, in the sense that other threads will not modify its value concurrently.
This protection does not extend to the object referenced by your local variable: depending on the object's inner construction, such as mutability and use of static variables, the object may or may not be thread-safe.
Note that local variables of primitive types and local variables referencing immutable objects are always thread-safe.
Yes, the statement local variables are thread safe comes with a couple of conditions.
Firstly, let's look at why local variables are thread safe. This is because the variables are allocated on the method's own stack frame, which is NOT shared with any other execution path.
So, it is important to note that the variable itself is thread-safe, NOT necessarily what it points to. In other words:
Primitive variables are completely thread safe, because the value is on the stack itself
Object references is a more complicated story, because the actual object is created on the heap and the stack frame just points to the heap memory.
In the image below, the integer variable is thread safe but the Object and Array are not.
Whether the object is thread-safe entirely depends on whether the class is designed to be thread-safe or not.
So if Machine is thread safe by itself through whatever way, then it can be safely stated that "the local variable machine" is thread safe.
It can always and unconditionally be stated that the 'local variable machine' is thread-safe', regardless of the thread-safety of any object it refers to.
Otherwise, it's not safe, even though 'machine' is a local variable.
If 'it' refers to the local variable, it is always thread-safe.
Is this understanding correct?
No. You are confusing variables with objects.
Local variables, such as machine in your example, are thread-safe, period.
Objects are or are not thread-safe depending on what's inside them, regardess of where and how they are referenced, i.e. in this case whether or not the object that is an instance of Machine is referenced by the local variable machine.

Thread safety of method

I see the following contruct for a mutable class:
public class Doubtful
{
public static Doubtful getInstance()
{
DoubtfulContext doubtfulcontext;//LOCAL HEAP VARIABLE
//...
doubtfulcontext = new DoubtfulContext(s1, new PrincipalName(s),
DefaultConfig.getInstance());
//...
doubtfulcontext.setDoubtfulStore(new DoubtfulStore(new File(s2)));
doubtfulcontext.setKeyTab(...);
doubtfulcontext.setSupportedEncryptionTypes(ai);
//...
return new Doubtful(doubtfulcontext);
}
// ...
}
While Doubtful may be non-mutable,but DoubtContext is definitely mutable.
Is this thread-safe?
What is the relevance of a local heap variable here?
Local variables are confined to the executing thread.They exist on the executing thread's stack and are not accessible to other threads. And this makes the execution of getInstance method thread safe.
As you have said Doubtful is immutable, and that makes it thread safe: multiple threads can work with the same Doubtful instance without effecting others working with the same Doubtful instance. Because the threads cannot change the instance variables (Doubtful is immutable) and method local variables are confined to the executing thread.
Now DoubtfulContext is mutable and you are publishing a reference to the DoubtfulContext instance which is created locally in the method getInstance:
doubtfulcontext = new DoubtfulContext(s1, new PrincipalName(s),
DefaultConfig.getInstance());
...
return new Doubtful(doubtfulcontext);//Publishes the reference to DoubtfulContext
which would violate the stack confinement. And there is a possibility that multiple threads can get access to the shared, mutable data of the same DoubtfulContext instance. If DoubtfulContext is a non-thread-safe object, then this would break your program.
Consider a thread T1 that invokes getInstance to get an instance of Doubtful and after that it might share the DoubtfulContext reference (that came along with Doubtful) with other threads:
1. Doubtful doubtful = Doubtful.getInstance();
2. DoubtfulContext doubtfulContext = doubtful.getDoubtfulContext();
3. new Thread(new SomeRunnable(doubtfulContext)).start();
4. doubtfulContext.chnageSomeState();
At line no 3, it creates a new thread of execution with the DoubtfulContext. Now two threads have the same DoubtfulContext. If DoubtfulContext is non-thread-safe (having non-synchronized access to instance variables), then this would break the thread safety of the program.
This construction looks threadsafe, if there is no method or function to access the doubtfulcontext elsewhere in the class (and if the doubtfulcontext is not modified either), and if... Basically if you use it right, it is threadsafe.
There are a lot of ifs in that sentence. It would be preferable to make the DoubtfulContext non-mutable also.
It's not clear what this code does to say for certain if it is the right choice. The question of thread safety is a question of what is mutable and if that object will ever be seen by more than one thread. Creating a new object that is stateful, but will only ever be seen by one thread is thread-safe. Creating an immutable object with all immutable members is thread-safe whether you return a new one or the same one repeatedly.
If you have mutable state, you have to know if the object will be seen by more than one thread. If yes, then you need to take measures to ensure that the mutable things are thread-safe.
Several options:
Make all of it immutable. Initialize it in a static block and store it in a static variable (I'm not really a big fan of statics - it would be cleaner and more flexible use a dependency injection framework like Guice and inject it - then the decision about whether it's a singleton or not is made at startup time).
If doubtfulContext is not shared, and is the only thing which is stateful - then it is stateful, but any future caller will get a new instance of it, then your method is fine. If the doubtfulContext will be passed between threads later, you may need to make that thread-safe independently
If you want to optimize by, say, only reading the same file once and sharing an object that represents the file, then you will need some kind of thread-safe cache

Why are local variables thread safe in Java

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]

Thread Confinement

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"

Categories

Resources