I am learning Threads synchronization in java and I have the following code :
class abs{
int x=0;
public void increment(){
for(int i =0 ; i<10 ; i ) {
//System.out.println(Thread.currentThread().getId());
x ;
System.out.println(x);
}
}
}
class thread_creation extends Thread{
abs t;
thread_creation(abs x){
t=x;
}
public void run() {
t.increment();
}
}
public class Test_sync {
public static void main(String[] args) {
abs ob = new abs();
thread_creation t1 = new thread_creation(ob);
thread_creation t2 = new thread_creation(ob);
t1.start();
t2.start();
}
}
When I run the code , I get the following output :
2
3
4
5
6
7
8
9
10
11
2
12
13
14
15
16
17
18
19
20
I have many questions regarding this output :
- Why the output didn't start with 1 ? Initially x= 0 , so when the first thread increments and output x , then we should see 1 in the output ?
- Why the output has value of 2 twice ?
I am very confused , so someone please explain why we got this output ?
CodePudding user response:
Because the threads use a single variable to count.
A x =1 (1)
B x =1 (2)
A starts print (2), and goes to sleep
B prints 2
B keeps working, incrementing x, printing 3 to 11
B goes to sleep
A finishes the print of "2" it started a while back
Clarification of followup questions:
x is owned by the object ob
of class abs
there is only one which is shared across threads.
i is owned by the function public void increment()
and there are two independent calls of it.
As to the behaviour of sleeping on printing... That's pretty much the whole point of threads. print takes forever from a cpu point of view and there are exclusive assets (there is only one console) involved
CodePudding user response:
Not a full answer, but responding to a comment:
Why both threads don't share the loop counter variable
i
?...
That's because i
is a local variable within the increment()
method. Each call to increment()
gets its own distinct i
, which is created when the method is called, and which lives only until the method returns.
...although they share the variable x ?
Your x
on the other hand is a member variable (a.k.a., a field) of the abs
class. Each instance of the abs
class gets its own distinct x
, and that x
lives as long as the instance lives. Your main()
method creates just one instance of abs
, and gives it to both threads.
What sets the two variables apart is where they are declared. i
is declared inside the increment()
method body. That's what makes it local. x
is declared outside of any method, but inside the declaration of class abs {...}
. That's what makes it an instance variable.*
* There are also static
variables that can be declared inside a class, but I won't go in to that here.