How to have a constant starting point for all threads java - java

If I am running 2 threads in java, and both these threads call a function, is an instance of each function created per thread? or can one thread interfere with the updates of the other thread?
for instance, say I have a function as such:
void test () {
int i=0;
for (i=0;i<20;i++) {
S.o.p(i);
}
}
If both threads call this function at the same time and thread1 has started the loop, and i=2 when thread2 comes in, would thread2 start at 2, or would it start from 0?

Local variables (for instance int i) are held only by the thread calling the function (each thread has its own stack and therefore locals will not be accessed by other threads). Memory not on the stack, such as static members, and non-static class members called by two threads) are accessible and modifiable by different threads.
To answer the question directly, both threads will operate independently (assuming S.o.p doesn't modify anything) as if the other thread were not running. If S.o.p Modifies some (e.g. static) value then both threads will modify it. Regardless, both thread will run in your for loop 20 times.

In Java, threads only share what's called 'shared mutable state'. Shared mutable state refers to instance variables in the class. For example, in the class below:
class account{
private int balance =0;
void test () {
int i=0;
for (i=0;i<20;i++) {
i++;
}
}
}
All threads that access the test method are entirely independent of each other because methods and variables in methods (local variables) are executed on a per thread basis.
However, if you were to mutate the this.balance variable in the test method you would be sharing state of that variable among threads. To do so safely, wherever you touch the this.balance variable you must synchronize the method for thread safety or use a synchronized block. But it's far better to use use atomic variables to avoid synchronization altogether.
That said, if S.o.p(...) is modifying shared mutable state then you need to use synchronized in the method signature or use a synchronized block.

Local variables of methods are not thread contentious so another thread will also start from i=0.
Only class level instances and variables define the state of an
object, so those are considered as thread contentious.
Local variables are stored in each thread's own stack. That means that local variables are never shared between threads

In your case you have the instance with method test with the local variable i. Local variables will be in stack per thread which means that all threads have own local variables. Note that you should synchronize access when you try to use data in heap (like fields of the instance) in multithreading environment. More info: https://docs.oracle.com/javase/tutorial/essential/concurrency/

Related

When is ThreadLocal preferred over Local Variables?

ThreadLocal in Java says that:
The ThreadLocal class in Java enables you to create variables that can only be read and written by the same thread. Thus, even if two threads are executing the same code, and the code has a reference to a ThreadLocal variable, then the two threads cannot see each other's ThreadLocal variables.
My question is: When we need to get a variable specific to a thread, can't we just declare that variable as a local variable inside a method? Because every thread has its own stack and thus it gets its own copy of variables. Am I missing something here?
ThreadLocal is is not an alternative to local variables. You use ThreadLocal for data that have to be static, but which must not be shared between threads.
static final ThreadLocal<MyFoo> myFoo =
ThreadLocal.withInitial(() -> new MyFoo());
If you have a ThreadLocal variable that is not static, then you're either doing something that's overly complicated, or you're doing something that's just plain wrong.
On the other hand, if you have any variable that is static (whether it is ThreadLocal or not), then you should be aware that that's a design choice that will limit your ability to test and grow the program.
ThreadLocal was meant for different purpose as per oracle documentation.
Have a look at intent of this class:
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).
Below code block generates unique identifiers local to each thread. A thread's id is assigned the first time it invokes ThreadId.get() and remains unchanged on subsequent calls.
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadId {
// Atomic integer containing the next thread ID to be assigned
private static final AtomicInteger nextId = new AtomicInteger(0);
// Thread local variable containing each thread's ID
private static final ThreadLocal<Integer> threadId =
new ThreadLocal<Integer>() {
#Override protected Integer initialValue() {
return nextId.getAndIncrement();
}
};
// Returns the current thread's unique ID, assigning it if necessary
public static int get() {
return threadId.get();
}
}
Coming back to your query:
When we need to get a variable specific to a thread, can't we just declare that variable as a local variable inside a method? Because every thread has its own stack and thus it gets its own copy of variables. Am I missing something here?
Yes. You are missing something here.
The scope of variable , which was declared inside a method ends with the method life cycle.
In case of ThreadLocal varaibles, each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible. You can re-enter the thread multiple times in it's life cycle and still you can retain the variable.
ThreadLocal could be best choice in scenarios when state needs to be
associated with thread e.g. for global variables (if semantic permits)
because ThreadLocal keeps values of variables confined to a thread; so
when a thread T runs get on it, thread T gets the value which was set
by itself not by any other threads.
from this article.
Local variable can be utilized when variable is inside thread's class itself and scope is local to each thread. Contrary to this, when variable is outside local scope and exists as part of shared code and semantic permits to keep copy of this variable per thread and not single copy for all threads then ThreadLocal is utilized.

Are local variables thread safe?

there have been already similar questions, but it doesn't answer the following problem. It's well known that values of fields are not necessarily immediately synchronized between threads. But is this also the case with local variables? Can the IllegalStateException be thrown?
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
final Integer[] shared = new Integer[1];
new Thread(new Runnable() {
#Override
public void run() {
shared[0] = 1;
mainThread.interrupt();
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
if (shared[0] == null) throw new IllegalStateException("Is this possible?");
}
}
Indeed, the value of shared will be the same for all threads. But the value of shared[0] also involves reading an array element, and that array element, like a field, may be subject to a data race.
Are you sure about shared being safe?
Yes, the Java Language Specification writes:
Local variables (§14.4), formal method parameters (§8.4.1), and exception handler parameters (§14.20) are never shared between threads and are unaffected by the memory model.
At the JVM level, each thread has its own local variables. If an anonymous class accesses a local variable of an enclosing method, the compiler rewrites this code to pass the value of the variable as a constructor parameter to the inner class, which will store it in a final field (this rewriting is why the compiler requires such a variable to be effectively final and definitely assigned), and replaces all accesses to this variable by an access to the final field. Due to the special guarantees the Java Memory Model gives for final fields, this access is safe even if it the object reference is published through a data race, provided that such publication only occurs after the object has completed construction.
Local variables are perfectly thread safe, because there is no way to share them with another thread in the first place.
Your example code is a wholly different beast, because you are actually asking about the value of a shared array referred to by a local variable. Thats two different things. The variable is perfectly safe (cannot change anyway, since its final), the contents of the array it refers to is not synchronized in any way, so its also not safe.
Edit: To elaborate a bit about your variable named "shared"
When you declare a local variable as final, java allows you to refer to that variable in the scope of an anonymous class defined within the visibility scope of said variable (Put simpler: from within the block where the variable was defined).
What looks like one variable, are actually two variables. The one you declared exists in the main thread. The moment the anonymous "new Runnable()" is created, a copy of the variable contents is made (it actually becomes a hidden final field in the anonymous class). So when you refer to "shared" within the run()-method you do not access the local variable "shared" in the main thread.
You can verify this by looking at the class files your example creates (there are two, one for the class, and one for the anonymous class) and use javap -v for both to have a look at the byte code generated.
Local variables that are visible to more than one thread are not thread safe. They have to be accessed through the regular mechanisms (synchronized, volatile, immutable, etc.).
Normally, you create a local variable and use it within one thread. When you are ready, you must Safely Publish that variable. After that point, all the normal thread safe mechanisms must apply.
Yes, local variables are thread safe because the are allocated in the stack. Threads, however, don't share the stack. They are unique for each variable.
shared is thread safe, its the state of the object it refers to thats not safe.
It's possible your main thread could throw that exception but highly unlikely.
Telling the anonymous thread start() does not necessarily mean the VM/OS will actually start your thread before the next part of the program executes. So your main thread could enter the sleep before the other thread even starts. If it got interrupted from an external event inside that sleep before the thread set the value you could end up with null.
The sleep on the main thread almost positively ensures the anon thread will run before the test of shared.
Think about what would happen if you removed the sleep and checked for null immediately after starting the new thread. On my system shared[0] was null about 50% of the times I ran your program modified to have the sleep removed.
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
final Integer[] shared = new Integer[1];
new Thread(new Runnable() {
public void run() {
shared[0] = 1;
mainThread.interrupt();
}
}).start();
if (shared[0] == null)
System.out.println("ouch");
}
The local variables are stored in the stack and not in the heap, so they are thread safe

Do different threads see the same version of a object referenced by a local variable?

Are multiple threads guaranteed to see the same version of a shared object to which they have a reference? Here is a code sample:
public static void main(String[] args) {
final AtomicBoolean flag = new AtomicBoolean(false);
new Thread(){
public void run() { possibly read and mutate flag }
}.start();
new Thread(){
public void run() { possibly read and mutate flag }
}.start();
while (!flag.get()) {
Thread.yield();
}
}
To be clear, I am wondering whether writes by the child threads to the shared object are seen by the parent and sibling threads.
Are multiple threads guaranteed to see the same version of a shared local variable in their scope.
In general, it depends on what you mean by "the same version". It also depends on the nature of the variable (e.g. how it is declared and initialized) ... and on how the threads use it.
(In general, Java doesn't do "versions" of variables. A thread accessing a shared variable or object will either see the latest state, or it won't. If it sees a state that isn't the latest state, then there are no guarantees as to what it will see. In particular, it may see something that doesn't directly correspond to any notional version of the object ... due to word-tearing and other cache-related memory artefacts.)
In your example you are using a final local variable within an inner class (in this case you have two anonymous inner classes). When you do that, the compiler creates a corresponding synthetic variable in the inner class that is initialized with the value of the variable in the method scope. The compiled inner class then refers to the value of the synthetic variable instead of the original variable.
In your example, it is guaranteed that the inner classes (e.g. your threads) will see the same (reference) value as in the original variable. Furthermore, it is guaranteed that they will (at least initially) see a consistent snapshot of whatever object it is that it references. (And since it is an AtomicXxxx class, it will always be consistent for all threads that can access it. Guaranteed.)
OK, so what about other cases:
If flag was a static or instance field that was also final, then we wouldn't have synthetic variables, and each nested class would be referencing the same shared variable. But it would all still work.
If flag was a static or instance field and it wasn't final, but nothing changed the field (after creating of the threads) then it would still be OK. (Though you could argue that this is fragile ... because something could change the field.)
If flag was a static or instance field and it wasn't final or volatile, then the threads would initially see the same state as the parent thread. But if either the original thread or any of the other threads changed the variable (etcetera), then the others are not guaranteed to see the new state ... unless they respective threads synchronize properly.
I would like to know if changes to flag made in one thread are seen immediately by the other two threads.
As I said above, it depends ...
In your example, the answer is "yes", because you use a final reference to AtomicBoolean.
If you had declared flag as a boolean and marked it as volatile, then the answer would be "yes".
If you had declared flag as a boolean and non-volatile, then the answer would be "no".
If flag was a final reference to an ordinary object with a mutable non-volatile boolean field, then the answer would also be "no". (The threads would all see the same object, but they wouldn't consistently see the latest state. The solution would be to use synchronized getters and setters, or equivalent.)
Yes, the two threads share the same final AtomicBoolean which is a class used to set the truth value. The variable flag itself can't be recreated because it is final. But you can perform actions on it to set value. Just like a final int[] can't be assigned to different size but you can change the value of what's inside.
final AtomicBoolean flag = new AtomicBoolean(false);
new Thread(){
public void run(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag.set(true);
}
}.start();
new Thread(){
public void run(){
flag.set(false);
}
}.start();
Thread.sleep(200);// comment this line, you see different results
System.out.println(flag);
In this case, yes. The Java Language Specification says that calling Thread.start() synchronizes-with all previous actions on the calling thread:
An action that starts a thread synchronizes-with the first action in the thread it starts.
This creates a happens-before relationship between all writes on your main thread (including any writes the constructor of the AtomicBoolean made to initialize itself) are made visible to the thread your main thread started.
A call to start() on a thread happens-before any actions in the started thread.
So basically you are good to go. Your AtomicBoolean object is visible to both threads, and they both see the same object.
This pattern is called Safe Publication, btw. You use it to safely publish an object you create (like your AtomicBoolean) so that other threads can see it. (And yes, Thread.start() isn't on the list there of ways to safely publish an object because Thread.start() isn't general enough. But it's the same idea, and works the same way.)
The local variable is not shared1, and being final means that there would be no worry of it changing even if it was the case. (A question about member variables would result in a different response although, excluding constructor leakage, a final member would provide the same guarantees.)
The same object is shared across threads; it will be the same object and will adhere to the defined AtomicBoolean contract.
A boolean value that may be updated atomically. See the java.util.concurrent.atomic package specification for description of the properties of atomic variables.
In short the package documentation specifies the following which in turn guarantees happens-before relationships.
get has the memory effects of reading a volatile variable.
set has the memory effects of writing (assigning) a volatile variable.
There are many questions relating to the thread-safey of volatile (and AtomicXYZ objects), eg. see Is a volatile int in Java thread-safe? and Is AtomicBoolean needed to create a cancellable thread?
1 Anonymous types, including Java 8 lambdas, do not create closures/lexical bindings to variables in scope and as such are not capable of sharing local variables; rather variables are synthesized with the value of the final (or effectively final) variable from the enclosing scope which is bound when the anonymous type is instantiated.

Are method parameters thread safe in Java?

Class Shared{
public void sharedMethod(Object o){
//does something to Object
}
}
//this is how threads call the shared method
run(){
sharedInstance.sharedMethod(someObject);
}
Now the o is being passed as the parameter to the method. And the same method is being called by multiple threads in parallel. Can we safely say that this code is thread safe?
There are two scenarios:
If the someObject is being shared among the threads
If every Thread has its own copy of someObject
No you cannot say that. Method parameters are local to threads, meaning each one has their own copy of the o reference variable, But if you call this method with the same object from multiple threads, then the argument will be shared between them (remember that Java is pass-by-value). In that case, you need to provide explicit synchronization to avoid troubles.
Yes, but only in two scenarios:
if every object you pass in the o parameter is immutable,
if your code guarantees that there is at most one thread working on the object referenced by o.
Otherwise - no, since the internal state of the object can be changed by multiple threads concurrently.
When you create a thread it will have its own stack created (method and local variables).
Two threads will have two stacks and one thread never shares its stack with any other thread.
It will not effect until you are calling this on same object.
If you call the same method in multiple threads, and pass it the same object, that object is absolutely not safe.
Treat it this way.
If your threads don't share any common resources, than it's impossible to have concurrency problems.
As much as we can tell from the information you provided, the only thing that can be shared here, is someObject. If it's thread-safe itself, or being copied for each thread, than your code is thread safe in general, unless there are other shared resources.
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.
EDIT
The LocalObject instance in this example is not returned from the method, nor is it passed to any other objects that are accessible from outside the sharedMethod() method.
Each thread executing the sharedMethod() method will make use of its own Object o as parameter.
So, the whole method sharedMethod() seems to be thread safe.
The only exception is of course, if one of the methods called with the Object o as parameter, stores the Object o instance in a way that allows access to it from other threads.

question about singleton classes and threads

I'm trying to learn about singleton classes and how they can be used in an application to keep it thread safe. Let's suppose you have an singleton class called IndexUpdater whose reference is obtained as follows:
public static synchronized IndexUpdater getIndexUpdater() {
if (ref == null)
// it's ok, we can call this constructor
ref = new IndexUpdater();
return ref;
}
private static IndexUpdater ref;
Let's suppose there are other methods in the class that do the actual work (update indicies, etc.). What I'm trying to understand is how accessing and using the singleton would work with two threads. Let's suppose in time 1, thread 1 gets a reference to the class, through a call like this IndexUpdater iu = IndexUpdater.getIndexUpdater(); Then,
in time 2, using reference iu, a method within the class is called iu.updateIndex by thread 1. What would happen in time 2, a second thread tries to get a reference to the class. Could it do this and also access methods within the singleton or would it be prevented as long as the first thread has an active reference to the class. I'm assuming the latter (or else how would this work?) but I'd like to make sure before I implement.
Thank you,
Elliott
Since getIndexUpdater() is a synchronized method, it only prevents threads from accessing this method (or any method protected by the same synchronizer) simultaneously. So it could be a problem if other threads are accessing the object's methods at the same time. Just keep in mind that if a thread is running a synchronized method, all other threads trying to run any synchronized methods on the same object are blocked.
More info on:
http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Your assumption is wrong. Synchronizing getIndexUpdater() only prevents more than one instance being created by different threads calling getIndexUpdater() at (almost) the same time.
Without synchronization the following could happen: Thread one calls getIndexUpdater(). ref is null. Thread 2 calls getIndexUpdater(). ref is still null. Outcome: ref is instantiated twice.
You are conflating the instantiation of a singleton object with its use. Synchronizing the creation of a singleton object does not guarantee that the singleton class itself is thread-safe. Here is a simple example:
public class UnsafeSingleton {
private static UnsafeSingleton singletonRef;
private Queue<Object> objects = new LinkedList<Object>();
public static synchronized UnsafeSingleton getInstance() {
if (singletonRef == null) {
singletonRef = new UnsafeSingleton();
}
return singletonRef;
}
public void put(Object o) {
objects.add(o);
}
public Object get() {
return objects.remove(o);
}
}
Two threads calling getInstance are guaranteed to get the same instance of UnsafeSingleton because synchronizing this method guarantees that singletonRef will only be set once. However, the instance that is returned is not thread safe, because (in this example) LinkedList is not a thread-safe queue. Two threads modifying this queue may result in unexpected behavior. Additional steps have to be taken to ensure that the singleton itself is thread-safe, not just its instantiation. (In this example, the queue implementation could be replaced with a LinkedBlockingQueue, for example, or the get and put methods could be marked synchronized.)
Then, in time 2, using reference iu, a method within the class is called iu.updateIndex by thread 1. What would happen in time 2, a second thread tries to get a reference to the class. Could it do this and also access methods within the singleton ...?
The answer is yes. Your assumption on how references are obtained is wrong. The second thread can obtain a reference to the Singleton. The Singleton pattern is most commonly used as a sort of pseudo-global state. As we all know, global state is generally very difficult to deal with when multiple entities are using it. In order to make your singleton thread safe you will need to use appropriate safety mechanisms such as using atomic wrapper classes like AtomicInteger or AtomicReference (etc...) or using synchronize (or Lock) to protect critical areas of code from being accessed simultaneously.
The safest is to use the enum-singleton.
public enum Singleton {
INSTANCE;
public String method1() {
...
}
public int method2() {
...
}
}
Thread-safe, serializable, lazy-loaded, etc. Only advantages !
When a second thread tries to invoke getIndexUpdater() method, it will try to obtain a so called lock, created for you when you used synchronized keyword. But since some other thread is already inside the method, it obtained the lock earlier and others (like the second thread) must wait for it.
When the first thread will finish its work, it will release the lock and the second thread will immediately take it and enter the method. To sum up, using synchronized always allows only one thread to enter guarded block - very restrictive access.
The static synchronized guarantees that only one thread can be in this method at once and any other thread attempting to access this method (or any other static synchronized method in this class) will have to wait for it to complete.
IMHO the simplest way to implement a singleton is to have a enum with one value
enum Singleton {
INSTANCE
}
This is thread safe and only creates the INSTANCE when the class is accessed.
As soon as your synchronized getter method will return the IndexUpdater instance (whether it was just created or already existed doesn't matter), it is free to be called from another thread. You should make sure your IndexUpdater is thread safe so it can be called from multiple threads at a time, or you should create an instance per thread so they won't be shared.

Categories