Reputation: 21
I am trying to run the following program for threads and expecting that the variable object should be updated by two different threads. Very strangely, it is just showing values 'addition -1' and 'multiply -2'. But when I am using debugger and debugging it step by step, then 'addition' and multiplication is happening as expected. If I put 'Thread.sleep' in 'run' method of 'P' for 1000 ms. It works fine. I have commented out the code of 'Thread.sleep', but if you uncomment it and run, you will find expected results. Can anyone clarify this to me, please?
public class TestingThreads {
public static void main(String[] args) {
Variable b = new Variable();
Thread tp = new Thread(new P(b));
Thread tq = new Thread(new Q(b));
tp.start();
tq.start();
try {
tp.join();
tq.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Variable {
int i = 0;
boolean on = true;
public synchronized void addition() {
if (!on) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i = i + 1;
on=false;
notify();
System.out.println("addition " + i);
}
public synchronized void multiply() {
if (on) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
i = i * 2;
on=true;
notify();
System.out.println("multiply " + i);
}
}
class P implements Runnable {
Variable b;
P(Variable b) {
this.b = b;
}
@Override
public void run() {
while (true) {
/*uncomment it and it will work fine.*/
/*try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
b.addition();
}
}
}
class Q implements Runnable {
Variable b;
Q(Variable b) {
this.b = b;
}
@Override
public void run() {
while (true) {
b.multiply();
}
}
}
Upvotes: 2
Views: 55
Reputation: 3572
You are hitting the top of the integers and wrapping around. Look before and after values of each operation:
addition pre: 0
addition post: 1
multiply pre: 1
multiply post: 2
addition pre: 2
addition post: 3
multiply pre: 3
multiply post: 6
addition pre: 6
addition post: 7
multiply pre: 7
multiply post: 14
addition pre: 14
addition post: 15
multiply pre: 15
multiply post: 30
addition pre: 30
addition post: 31
multiply pre: 31
multiply post: 62
addition pre: 62
addition post: 63
multiply pre: 63
multiply post: 126
addition pre: 126
addition post: 127
multiply pre: 127
multiply post: 254
addition pre: 254
addition post: 255
multiply pre: 255
multiply post: 510
addition pre: 510
addition post: 511
multiply pre: 511
multiply post: 1022
addition pre: 1022
addition post: 1023
multiply pre: 1023
multiply post: 2046
addition pre: 2046
addition post: 2047
multiply pre: 2047
multiply post: 4094
addition pre: 4094
addition post: 4095
multiply pre: 4095
multiply post: 8190
addition pre: 8190
addition post: 8191
multiply pre: 8191
multiply post: 16382
addition pre: 16382
addition post: 16383
multiply pre: 16383
multiply post: 32766
addition pre: 32766
addition post: 32767
multiply pre: 32767
multiply post: 65534
addition pre: 65534
addition post: 65535
multiply pre: 65535
multiply post: 131070
addition pre: 131070
addition post: 131071
multiply pre: 131071
multiply post: 262142
addition pre: 262142
...
multiply pre: 1073741823
multiply post: 2147483646
addition pre: 2147483646
addition post: 2147483647
multiply pre: 2147483647
multiply post: -2
addition pre: -2
addition post: -1
multiply pre: -1
multiply post: -2
addition pre: -2
The same thing will happen with a sleep, just much more slowly. :)
Upvotes: 3