Reputation: 1356
I have two files, App.java
and Runner.java
App.java
-->
public class App {
private static Thread thread1 = new Runner(1);
private static Thread thread2 = new Runner(2);
public static void main(String[] args) throws InterruptedException {
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.printf("Count = %d\n", Runner.getCount());
}
}
Runner.java
-->
public class Runner extends Thread {
private volatile static int count = 0;
private int option = 0;
private synchronized void increment() {
count++;
}
private synchronized void decrement() {
count--;
}
public Runner(int option) {
this.option = option;
}
public static int getCount() {
return count;
}
@Override
public void run() {
switch (option) {
case 1:
for (int i = 1; i <= 10000; i++) {
increment();
}
break;
case 2:
for (int i = 1; i <= 10000; i++) {
decrement();
}
break;
}
}
}
Here I am trying to create two threads
from main
thread
and access a common variable
from both the threads where both the threads
will manipulate this common variable
at the same time.
I am trying to create a demo for implementation for the synchronized
keyword.
In my example, in Runner.java
-
I am making Runner
class
a child
class of Thread
using extends
keyword
and overriding
the run()
method
in body.
Next, I am using a constructor
to get an option
and running the respective code in run()
method in a switch - case
block
. The common variable is count
which is static
with initial value 0.
There are two methods
, both use the synchronized
keyword
- increment()
and decrement()
which increase and decrease the value of count by 1 respectively.
For option 1
run()
method uses a for loop
to run increment()
10,000 times.
For option 2
run()
method uses a for loop
to run decrement()
10,000 times.
As such the end value of count
should be 0.
In App.java
-
I am creating two threads
- thread1
, thread2
which are instances of Runner class
and passing constructor
argument
1 and 2 respectively.
I am running the two threads
using thread.start()
and waiting for completion of the two threads
using thread.join()
Now, I am printing the value of count
. The value is expected to be 0. But it is not. In each execution it is near to 0 but not 0.
So, where am I going wrong and how to correct my code?
Upvotes: 1
Views: 31
Reputation: 18320
count
is static meaning there is only one such variable.
Both increment
and decrement
are not static which means they are synchronized on this
- that is two separate Runner
instances.
Make those method static:
private synchronized static void increment() {
count++;
}
private synchronized static void decrement() {
count--;
}
or use explicit mutex object:
private static int count = 0;
private static Object mutex = new Object;
private int option = 0;
private void increment() {
synchronized (mutex) {
count++;
}
}
private void decrement() {
synchronized (mutex) {
count--;
}
}
Upvotes: 1