could you please help me?
I have a function 'f' in Java. The function works in multithreading environment
f() {
SomeObject someO = new SomeObject();
function1(someO);
.
.
.
function7(someO);
}
The problem: first thread enters into the function 'f' and creates new instance of SomeObject then calls function1, function2 ect. An instant later second thread enters into the method and creates new instnce of SomeObject when the first thread is in function4. The question is which instance of SomeObject will be processing by first thread in the rest of function 5, 6, 7 ?
The first thread has its instance of SomeObject (aka some0) as a local variable, therefore it is local to that stackframe and hence to that thread. It will only be able to reference that instance of some0.
Any other thread calling f() will create a different instance, also named some0, and only be able to reference that copy of it.
These are the rules for a local variable. If some0 were an instance variable -- i.e., declared outside f() -- then that variable could be referenced by different threads if they called f() on the same instance of whatever class holds the definition of f().
Those are the rules -- here's a more complete explanation.
Local variables are declared on the stack; that means that, for any variables declared within a method, there is space for their references in a 'stack frame' for that invocation of that method. Each time a method is invoked, there is space on the stack allocated for all the local variables in the method, and therefore their references are separate from any other invocation of that method. So if a different thread invokes the method, it gets a different stack frame for the local variables.
The same thing happens in a recursive procedure, i.e., if f() were to call itself. The local variable references would still be separate for each invocation of f(), i.e., each recursive call would have its own copy of them. Otherwise it would be very difficult to use recursion at all.
First thread will process first instance of SomeObject.
Every Thread creates its own stack. and whatever methods it is calling and whatever local objects it is creating, will live in that stack and these objects are not affected by other thread. So in your case thread 1 one processing is not going to affect by thread 2 processing.
Related
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/
If I have one instance of an object A and it has an instance method foo() with only variables created and used in that method is that method thread safe even if the same instance is accessed by many threads?
If yes, does this still apply if instance method bar() on object A creates many threads and calls method foo() in the text described above?
Does it mean that every thread gets a "copy" of the method even if it belongs to the same instance?
I have deliberately not used the synchronized keyword.
Thanks
Yes. All local variables (variables defined within a method) will be on their own Stack frame. So, they will be thread safe, provided a reference is not escaping the scope (method)
Note : If a local reference escapes the method (as an argument to another method) or a method works on some class level or instance level fields, then it is not thread-safe.
Does it mean that every thread gets a "copy" of the method even if it belongs to the same instance
No, there will be only one method. every thread shares the same method. But each Thread will have its own Stack Frame and local variables will be on that thread's Stack frame. Even if you use synchronize on local Objects, Escape Analysis proves that the JVM will optimize your code and remove all kinds of synchronization.
example :
public static void main(String[] args) {
Object lock = new Object();
synchronized (lock) {
System.out.println("hello");
}
}
will be effectively converted to :
public static void main(String[] args) {
Object lock = new Object(); // JVm might as well remove this line as unused Object or instantiate this on the stack
System.out.println("hello");
}
You have to separate the code being run, and the data being worked on.
The method is code, executed by each of the threads. If that code contains a statement such as int i=5 which defines a new variable i, and sets its value to 5, then each thread will create that variable.
The problem with multi-threading is not with common code, but with common data (and other common resources). If the common code accesses some variable j that was created elsewhere, then all threads will access the same variable j, i.e. the same data. If one of these threads modifies the shared data while the others are reading, all kinds of errors might occur.
Now, regarding your question, your code should be thread safe as long as your variables are defined within bar(), and bar() doesn't access some common resource such as a file.
You should post some example code to make sure we understand the use case.
For this example:
public class Test {
private String varA;
public void doSomething() {
String varB;
}
}
If you don't do anything to modify varA in this example and only modify varB, this example is Thread Safe.
If, however, you create or modify varA and depend on it's state, then the method is NOT Thread Safe.
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.
I used to think that, intuitively speaking, a constructor in Java is the thing that makes an object, and that nothing can touch that object until its constructor returns. However, I have been proven wrong about this over and over again:
uninitialized objects can be leaked by sharing this
uninitialized objects can be leaked by a subclass accessing it from the finalizer
uninitialized objects can be leaked to another thread before they're fully constructed
All of these facts violate my intuition of what I thought a constructor is.
I can no longer with confidence say what a constructor actually does in Java, or what it's meant to be used for. If I'm making a simple DTO with all final fields, then I can understand what the use of the constructor is, because this is exactly the same as a struct in C except it can't be modified. Other than that, I have no clue what constructors can be reliably used for in Java. Are they just a convention/syntactic sugar? (i.e If there were only factories that initialize objects for you, you would only have X x = new X(), then modify each field in x to make them have non default values - given the 3 facts above, this would be almost equivalent to how Java actually is)
I can name two properties that are actually guaranteed by constructors: If I do X x = new X(), then I know that x is an instance of X but not a subclass of X, and its final fields are fully initialized. You might be tempted to say that you know that constructor of X finished and you have a valid object, but this is untrue if you pass X to another thread - the other thread may see the uninitialized version (i.e what you just said is no different than the guarantees of calling a factory). What other properties do constructors actually guarantee?
All of these facts violate my intuition of what I thought a constructor is.
They shouldn't. A constructor does exactly what you think it does.
1: uninitialized objects can be leaked by sharing this
3: uninitialized objects can be leaked to another thread before they're fully constructed
The problem with the leaking of this, starting threads in the constructor, and storing a newly constructed object where multiple threads access it without synchronization are all problems around the reordering of the initialization of non-final (and non-volatile) fields. But the initialization code is still done by the constructor. The thread that constructed the object sees the object fully. This is about when those changes are visible in other threads which is not guaranteed by the language definition.
You might be tempted to say that you know that constructor of X finished and you have a valid object, but this is untrue if you pass X to another thread - the other thread may see the uninitialized version (i.e what you just said is no different than the guarantees of calling a factory).
This is correct. It is also correct that if you have an unsynchronized object and you mutate it in one thread, other threads may or may not see the mutation. That's the nature of threaded programming. Even constructors are not safe from the need to synchronize objects properly.
2: uninitialized objects can be leaked by a subclass accessing it from the finalizer
This document is talking about finalizers and improperly being able to access an object after it has been garbage collected. By hacking subclasses and finalizers you can generate an object that is not properly constructed but it is a major hack to do so. For me this does not somehow challenge what a constructor does. Instead it demonstrates the complexity of the modern, mature, JVM. The document also shows how you can write your code to work around this hack.
What properties are guaranteed by constructors in Java?
According to the definition, a constructor:
Allocates space for the object.
Sets all the instance variables in the object to their default values. This includes the instance variables in the object's superclasses.
Assigns the parameter variables for the object.
Processes any explicit or implicit constructor invocation (a call to this() or super() in the constructor).
Initializes variables in the class.
Executes the rest of the constructor.
In terms of your 3 issues, #1 and #3 are, again, about when the initialization of non-final and non-volatile fields are seen by threads other than the one that constructed the object. This visibility without synchronization is not guaranteed.
The #2 issue shows a mechanism where if an exception is thrown while executing the constructor, you can override the finalize method to obtain and improperly constructed object. Constructor points 1-5 have occurred. With the hack you can bypass a portion of 6. I guess it is in the eye of the beholder if this challenges the identity of the constructor.
From the JLS section 12.5:
12.5. Creation of New Class Instances
Just before a reference to the newly created object is returned as the
result, the indicated constructor is processed to initialize the new
object using the following procedure:
Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
If this constructor begins with an explicit constructor invocation (§8.8.7.1) of another constructor in the same class (using this), then
evaluate the arguments and process that constructor invocation
recursively using these same five steps. If that constructor
invocation completes abruptly, then this procedure completes abruptly
for the same reason; otherwise, continue with step 5.
This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If
this constructor is for a class other than Object, then this
constructor will begin with an explicit or implicit invocation of a
superclass constructor (using super). Evaluate the arguments and
process that superclass constructor invocation recursively using these
same five steps. If that constructor invocation completes abruptly,
then this procedure completes abruptly for the same reason. Otherwise,
continue with step 4.
Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable
initializers to the corresponding instance variables, in the
left-to-right order in which they appear textually in the source code
for the class. If execution of any of these initializers results in an
exception, then no further initializers are processed and this
procedure completes abruptly with that same exception. Otherwise,
continue with step 5.
Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly
for the same reason. Otherwise, this procedure completes normally.
**
Unlike C++, the Java programming language does not specify altered rules for method >dispatch during the creation of a new class instance. If methods are invoked that are >overridden in subclasses in the object being initialized, then these overriding methods >are used, even before the new object is completely initialized.
And from JLS 16.9:
Note that there are no rules that would allow us to conclude that V is
definitely unassigned before an instance variable initializer. We can
informally conclude that V is not definitely unassigned before any
instance variable initializer of C, but there is no need for such a
rule to be stated explicitly.
Happens before 17.4.5:
Threading 17.5.2:
A read of a final field of an object within the thread that constructs
that object is ordered with respect to the initialization of that
field within the constructor by the usual happens-before rules. If the
read occurs after the field is set in the constructor, it sees the
value the final field is assigned, otherwise it sees the default
value.
A class contains constructors that are invoked to create objects from the class blueprint.
This is what Oracle says about constructors.
Now to your point.
intuitively speaking, a constructor in Java is the thing that makes an object, and that nothing can touch that object until its constructor returns.
So according to the official documentation, your assumption is not right. And the point 1 and 2 are the abuse of the rules and behaviors of Java, unless you consciously want to leak your objects! As also being irrelevant to Constructor, I will skip discussing these points.
Now if we talk about your 3rd point, in multi-threaded environment there is nothing that can guarantee you about the consistency of your code, unless "properly synchronized blocks" or "the atomic instructions". As object creation is not a synchronized nor an atomic instruction, there is no guarantee of being consistent! There is nothing the Constructor can do with it. In other words its not the responsibility of the Constructor to make your object creation atomic.
Now, the answer to your question, "What other properties do constructors actually guarantee?" is somewhat easy. Constructors are merely nothing but special type of methods, that are invoked during object creation from the blue print of the class. So it can guarantee nothing, unless you give it a chance to be executed consistently like any other methods. It after being consistently executed it can guarantee you that, your object is created and initialized as you wanted and instructed in it.
constructors is java are just used to initialize the state of the object created..nothing more.
class A
{
B b;
public A()
{
b = new B(this);
//initialization of class A variables
}
public void meth1()
{
}
}
class B
{
A a;
public B(A a)
{
this.a = a;
}
}
I know that this reference shouldn't be passed in this way,but what happens if this is done
Some other class calls the class A constructor. when is the "this" reference actually allocated memory? would it be assigned memory as soon as A's constructor is called before even super() is called.
Suppose class B is a thread and since B has A's reference can B call the methods on A before A's constructor doesn't even return if "this" reference is not allocated memory yet.
The memory for the object is allocated before any constructor is executed. Otherwise the constructor would have not place to write the values of the variables.
Therefore you can pass out a reference to the current object (a.k.a this) to other pieces of code inside the constructor.
As you noted, the object is not fully constructed at that time and it's a bad idea to actually do that, but "just" because the values of the object can be in an inconsistent state. The memory is already allocated and reserved for that object at this point in time.
this is just a reference to the "current object", which you could think of as just another parameter that any non-static method gets. In fact in that's actually how the JVM treats it. See JVMS §2.6.1 Local Variables:
On instance method invocation, local variable 0 is always used to pass a reference to the object on which the instance method is being invoked (this in the Java programming language).
So the direct answer to "when is this allocated" is effectively: Whenever you call a method on an object.
this refers to current object and any object is allocated memory using "new"
The memory is allocated when JVM is processing new instruction. If for example your code looks like:
A a = new A();
^
here the memory for A is allocated
It indeed could be a problem to pass this to B. Constructor of B can invoke instance method of A before the constructor of A has been finished. You should move line to the end of constructor of A to avoid possible problems. Alternatively you could manage the object lifecycle from outside using setters.
this is assigned before the constructor is called. In fact, the super() call is not necessary. It only ensures that the creation stuff of the parent class is done, which doesn't matter if the parent class is Object. Also, A's methods are usable as soon as the object is created (even before the constructor is called) so if B got the reference to A in the constructor, it can use A's methods just like A itself in the constructor. Just be sure to make A's methods so that they can be used when A is not fully initialized, or just create and start B after the initialization is complete.
As long as you don't modify A or call methods on A or it's members in the constructor of B it will work. ( See other answers)
If you call a method on an not completely initialized object (after construction) it's not defined what happens. Especially if you use multiple threads (see memory barrier).
More on this topic:
How do JVM's implicit memory barriers behave when chaining constructors?