Static method access to a non static variable inside a thread - java

I have:
public class UTIL{
public static void met(){
do_something(){
print(A.m());
}
}
}
public class A{
public <type> m;
public <type>static m(){
return m;
}
}
Now:
Thread A contains instance of class A
Thread B contains instance of class A
From Thread B, at some point UTIL.met is called.
Question:
When UTIL.met is called, will it use m from the instance of A in Thread B?

When UTIL.met is called, will it use m from the instance of A in Thread B?
No, it doesn't matter if Thread A has one instance and Thread B has another. A.m is static and common for all instances.
But it is definitely the case that if the variables are static, then both threads will use the same variable.
(In other words, without proper synchronization, you'll have nasty race-conditions.)

m is a class variable, so is is actually common for all instances.
UTIL.met() will use the same instance of m that is "being held" [or can be accessed is a better terminology...] in all instances of A.

m is defined as a static variable in A. So it will common/shared among all instances of A.
If m is not static on the other hand, then of course each instance will have its own copy.
Well since thread A and thread B each contains own instance of class A, then each thread will use its instance of A.
is that what you want to achieve or you wanted to share m between instances??

Related

Fork and join concept lagging

This is a sample code which i wrote this just for you to understand my problem which writtens below.
This is class which has a examplemethod which calculate some value for different a;
public class Class1{
public int examplemethod(int a){
int k = a*2;
int b=k+1;
......some more manipulation
return k;
}
}
Below class will call the above method parallely
public class Class2 extends RecursiveTask<Integer>{
int a=0;
Class1 obj;
public Class2(int a, Class1 obj){
this.a = a;
this.obj=obj;
}
#Override
protected Integer compute () {
return obj.examplemethod(a);
}
public static void main(Strings[] args){
List<Class2> list =new ArrayList<Class2>();
Class1 obj = new Class1();
for(int i=4;i<7;i++){
Class2 obj2=new Class2(obj);
obj2.fork();
list.add(obj2);
}
int arr[]=new int[4];
int i=0;
if(list.size>0){
for(Class2 ob:list){
arr[i++]= ob.join();
}
}
}
}
I am creating three object of class2 in the for loop so suppose 1st fork will compute the value using a=4 but while it is computing in the examplemethod, cpu shedule another thread let say fork 2 with a=5 and save program counter for fork 1 thread, now while computing value using a=5 it changes some variable inside the examplemethod which was earlier changes by fork1, so now my problem is, if examplemethod is resource which was shared among all the object of that class and if one object do some changes in the function and in the middle(thread switching) some other object came and change the same variable then my output will get affected but the problem is i am getting the right answer, so where my concept lagging in parallel threading, Threads will share a common resource so where is my critical section in my code.
Variables declared inside a method are local variables, having specific values for the particular method invocation. You should understand that concept independently of multi threading aspects first. E.g. what will the following program print:
public class Test {
public static void main(String[] args) {
test(5);
}
private static void test(int i) {
System.out.println("enter test with "+i);
if(i>0) test(i-1);
System.out.println("leave test with "+i);
}
}
The local nature of these variables doesn’t change when multiple threads execute the same method. There is no interference between these executions.
Likewise, instance variables, i.e. member variables declared in a class without the static modifier. hold values specific to a particular object instance, hence, if you create multiple instances, they can have distinct values for these variables without affecting each other.
These are the building blocks which are used to build multi-threaded programs without the need to do thread synchronization all the time. If you create distinct objects representing the different tasks to be executed and these tasks execute only methods using these objects and/or their method parameters (method parameters are local variables) to compute results, the tasks are already isolated.
The things you must not do, are modifying static variables or instance variables of shared objects. In your code, there are no shared objects.
Which resource is shared between threads in your code?
in short your class1 is thread safe, because variables defined inside method cannot be changed by another thread.
While class2 is not - if and only if two threads can use same instance of class2 at the same time (aka Singleton) and thread changes some instance variable, while another one use it.
You have only one instance variable in class2 - int a.
But in the code I do not see any kind of Singleton or instance variable "a"change...
Each thread has a new instance of class2: Class2 obj2=new Class2();
(actually it must be kind of Class2 obj2=new Class2(aValue);)
Did I miss something there?

Why can't I refer enclosing class's non-static var from its inner class's non-static method?

In my awareness, non-static method will be assigned "this" variables for its class obj & all enclosing classes.
public class TestNested {
int a=4;
public static class a{
int a=5;
static int c=10;
class b{
int a=6;
void aaa(){
int a=7;
TestNested t=new TestNested();
System.out.println(this.a);
System.out.println(b.this.a);
System.out.println(TestNested.a.b.this.a);
System.out.println(TestNested.a.this.a);
System.out.println(a.this.a);
System.out.println(t.a);
System.out.println(TestNested.this.a);
}
}
}
void r(){
TestNested t=new TestNested();
TestNested.a a=new TestNested.a();
a.b b=a.new b();
b.aaa();
}
public static void main(String[] args) {
TestNested t=new TestNested();
t.r();
}
}
in this case the final statement of void aaa() is System.out.println(TestNested.this.a); will be sentenced to cause compilation error with the reason :'com.xxx.TestNested.this' cannot be referenced from static context, that's really confusing me because the this var that points to TestNested should be the non-static hidden var of the method itself,then why it can't use its own var?
Or if my awareness is wrong that each that var is assigned in each class enclosed from the method's class, but the void aaa() isn't a static method which means it can reference non-static var rite? or even the method isn't static, but if one of its enclosing class is static, it'll be automatically recognized as static member?
This is because your nested class a is not an inner class of TestNested. It is a static nested class, meaning that it is not linked to a particular instance of TestNested.
Note: an inner class is a non-static nested class.
What instance of TestNested would you expect your expression TestNested.this to refer to?
You can see, by the way, that you're not referring to your variable t here:
TestNested.a a=new TestNested.a();
Which points out that the object a is not linked to t at all.
In my above answer, I assumed it was clear to you what you were doing with this. It appears it is not the case, according to your comments, so I'm going to try and clarify it here.
First of all, this always refers to an object: an instance of a class.
Let's assume we're in the context of a non-static method in the class b. Because the method is non-static, the code will be executed relatively to a particular instance of b. I take the shortcut to refer to this particular instance as "the instance of b you're in".
Since b is an inner class of a, no instance of b can exist outside an instance of a. This means the instance of b you're in is enclosed in an instance of a. I take the shortcut to refer to this particular instance as "the instance of a you're in" (Technically, you're in a b which is in an a).
So, in this context of a non-static method of b:
this refers to the instance of the b you're in. It is the standard use of this keyword.
b.this, a.b.this or TestNested.a.b.this are the same as this here, the difference is only that you qualify more precisely the class b.
a.this or TestNested.a.this both refer to the instance of a you're in (TestNested.a is just a more precise qualification for a). This a object exists because b is an inner class of a, which means that every instance of b is linked to an instance of a. This is the only way to refer to the instance of a.
TestNested.this would refer to the instance of TestNested you're in. But you're not in any instance of TestNested, so it does not mean anything, hence the compile error. You're in an instance of b, which is within an instance of a (because b is an inner class of a). The instance of a exists by itself because a is a static nested class of TestNested, so it is not linked to an instance of TestNested.
TestNested.a <-- references a static variable of a static class
this.a <-- references an instance variable of an object
TestNested.this <-- tries to reference an object from a static context, but "this" does not exist in a static context.
You can reference static content from non-static, but not vice-versa.

Are static class members static in Java?

In the below code, are b and show inherently static?
public class A {
public static class B {
private int b = 0;
public void show() {
System.out.println(b);
}
}
}
No they aren't static. You need to create an instance of B to access them.
The static keyword in your code example means that instances of B can be created without an instance of A.
If B was not static:
Instances would have an implicit reference to an instance of A.
The only way to create them would be to use new B() inside class A, or using syntax like new A().new B().
Methods in B can refer to A.this (the implicit reference to an instance of A).
Methods in B can refer to A.this.someField (using that implicit reference).
Methods in B can call instance (non-static) methods in A.
However, because B is static:
Instances do not have a reference to an instance of A - you don't need an A to create a B.
Instances can be created using new A.B() (or just new B() from within in class A)
Methods in B cannot refer to A.this.
Methods in B cannot access fields in A (unless passed in as a parameter).
Methods in B cannot call instance (non-static) methods in A.
They are not static. They are instance fields in B.
Meaning you need to have an instance of B to get/set them.
B is static in A but that does not make those fields of B static.
You can create many instances of B without any reference to A.
So B is static class in A but the same is not true for B's instance fields.
The static keyword has two meanings that are actually quite different and that can be confusing.
Static on a variable/method means that it exists at the class level, not the instance level. This means that you only have one copy of that variable/method no matter how many instances of the class you create.
Static on an inner class though just means that the class does not depend upon its outer class. In your example you can create a new B() without having an A. If you didn't have the static keyword on the class you could not create a new B() unless it was within an instance of A.
B is a static inner class of A.
Need to instantiate B.
A.B innerObject = new A.B();
innerObject.show();
The identifier static has a specific purpose here that many people don't immediately grasp. I'm going to take your code and change it a bit.
public class A {
private int a;
public A(int a) {
this.a = a;
}
public class B {
public void show() {
System.out.println(a);
}
}
}
Now, what's happening in class B? Because B is a non-static class, it has access to other non-static members in class A. Essentially, it states that every class A object has their own flavor of class B objects, even thought they are functionally the same. For us to get that same behavior if B was a static class:
public class A {
private int a;
public A(int a) {
this.a = a;
}
public int getA() { return a; }
public static class B {
public void show(A a) {
System.out.println(a.getA());
}
}
}
Here, this implies that the flavor of B objects doesn't change depending on which A object created it. The B class is static so that it cannot access non-static members of the A class object that created it and must access those members explicitly from whichever A object it wants to interact with.
In the previous implementation, a B object would seamlessly access fields and non-static methods of the A object that created it.
These are two different behaviors and often it's clear exactly which one fits your objective.

Making a class Thread-Safe

Given:
public class TestSeven extends Thread {
private static int x;
public synchronized void doThings() {
int current = x;
current++;
x = current;
}
public void run() {
doThings();
}
}
Which statement is true?
A. Compilation fails.
B. An exception is thrown at runtime.
C. Synchronizing the run() method would make the class thread-safe.
D. The data in variable "x" are protected from concurrent access problems.
E. Declaring the doThings() method as static would make the class thread-safe.
F. Wrapping the statements within doThings() in a synchronized(new Object()) { } block would make the class thread-safe.
isn't it enough to mark doThings() as synchronized in order to make that class Thread-safe ? i see that the correct answer is D but the Model answer of this question is E, But i don't understand why?
E. Declaring the doThings() method as static would make the class thread-safe.
That is kind of a tricky answer. The method is already synchronized, but on the instance, whereas the state is in a static field, i.e. on the class. Making it static synchronized is indeed the correct answer, because then it synchronizes on the class, not on a (meaningless) instance.
D. The data in variable "x" are protected from concurrent access problems.
private static int x;
This is a static variable. It is shared by all instances of the class, so synchronizing on individual instances is not helpful, in the same way as F would not be helpful, which synchronizes on a complete throw-away dummy object.
According to the language spec:
A synchronized method acquires a monitor (§17.1) before it executes.
For a class (static) method, the monitor associated with the Class
object for the method's class is used.
For an instance method, the monitor associated with this (the object
for which the method was invoked) is used.
This means that in the code you provided the synchronized keyword causes the method to acquire a lock on this before executing the body of the method. However, since x is static that doesn't ensure that the update to x will be atomic. (Another instance of the class could enter the synchronized region and do an update at the same time since they have different this values and thus different locks.)
However, declaring doStuff static will make all calls to the method acquire the same lock (the one on the Class) and thus would ensure mutual exclusion in the method body.
The specifications is really spelling out that:
class A {
static synchronized void doSomething() {
// ...
}
}
is literally the same thing as
class A {
static void doSomething() {
synchronized(A.class) {
// ...
}
}
}
Similarly:
class B {
synchronized void doSomething() {
// ...
}
}
is literally the same thing as
class B {
void doSomething() {
synchronized (this) {
// ...
}
}
}
By way of synchronizing the doThings() method, you are holding the lock for a particular TestSeven object. However, static variables of the class does not belong to the specific instance of the object itself. They belong to the Class object TestSeven.class. So, either you could go for a
synchronized (TestSeven.class){
int current = x;
current++;
x = current;
}
inside your doThings() method which is acquiring the Class lock inside an instance lock which is overdoing things. So, you could mark the method as static so that you end up acquiring the lock of the Class object alone.
Since x is static other threads could modify it at the same time doThings method is running. Making doThings static will stop this.
I agree with you that the correct answer is D.
I would say that E is incorrect because if I set doThings() as static and remove the synchronized keyword, I could just start up 50 TestSeven threads and it could result in incorrect x value.
Note:
I was wrong here, I missed the point that synchronized method without static actually use the instance as the lock monitor instead of the Class itself.

Java Static Synchronized [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do synchronized static methods work in Java?
Can someone make me understand the fundamental difference between the following two functions:
public static void synchronized f() {… }
and
public void synchronized f() {… }
In the case of
public void synchronized f(){...}
The synchronization is per instance of the of enclosing class. This means that multiple threads can call f on different instances of the class.
For
public static void synchronized f(){...}
Only one thread at a time can call that method, regardless of the number of instances of the enclosing class.
Technically, the monitor taken by synchronized in the first example is the of the object instance and the monitor take in the second example is that of the Class object.
Note that, if you have classes of the same name in different ClassLoaders, the do not share the same monitor, but this is a detail you're unlikely to encounter.
In a "static synchnronized" method, the lock that is synchronized against is on the class itself; in a "synchornized" method, the lock is on the object. Note that this means that a "static synchronzied" method will not be blocked by a running "synchronzied" method, and vice versa. For more info, see: http://geekexplains.blogspot.com/2008/07/synchronization-of-static-and-instance.html
I think:
public void synchronized f() {… } synchronizes on object itself (this)
public static void synchronized f() {… } synchronizes on Class instance of an object (object.getClass() or SomeClass.getClass)
I can be wrong
Assuming the method f is in a class Foo. The static version will lock on the the static method call at the class level (the object returned by getClass() or Foo.class). The non static version will lock for particular instances of that class, so lets say:
Foo x = new Foo();
Foo y = new Foo();
// Locks method f of instance x, but NOT for y.
x.f();
In the static instance a call to f() will lock for both versions so only one method call to f would be executing at one time.

Categories

Resources