Reputation: 17
```
package programs;
public class TestThreads {
public static void main(String[] args) {
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
Thread one = new Thread(t1);
Thread two = new Thread(t2);
one.start();
two.start();
}
}
class Accum{
private static Accum a = new Accum();
private int counter = 0;
private Accum() {
}
public static Accum getAccum() {
return a;
}
public void updateCounter(int add) {
counter +=add;
}
public int getCount() {
return counter;
}
}
class ThreadOne implements Runnable{
Accum a = Accum.getAccum();
@Override
public void run() {
for(int x=0;x<98;x++) {
a.updateCounter(1000);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("one "+ a.getCount());
}
}
class ThreadTwo implements Runnable{
Accum a = Accum.getAccum();
@Override
public void run() {
for(int x=0;x<99;x++) {
a.updateCounter(1);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("two "+ a.getCount());
}
}
```
The expected output should be as below
One 98098 Two 98099
But I am getting values same for both One and Two.
Is this expected or both should result in different values?
When it comes to thread priorities eventhough the jvm scheduler takes the role to choose the turn of which thread should execute first, what about the results of this program where two void run programs of for loop with 98 and 99 which should result in two different values else the same
Upvotes: 0
Views: 48
Reputation:
Maybe make the methods and fields in the Accum
class static, because then it is saved in a general place and not an instance...
Code:
class Accum{
private static Accum a = new Accum();
private static int counter = 0;
private Accum() {
}
public static Accum getAccum() {
return a;
}
public static void updateCounter(int add) {
counter +=add;
}
public static int getCount() {
return counter;
}
}
class ThreadTwo implements Runnable{
@Override
public void run() {
for(int x=0;x<99;x++) {
Accum.updateCounter(1);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("two "+ Accum.getCount());
}
}
class ThreadOne implements Runnable{
@Override
public void run() {
for(int x=0;x<98;x++) {
Accum.updateCounter(1000);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("one "+ Accum.getCount());
}
}
I am not very experienced in Java yet, so this might not work... [EDIT] I tested it and I believe it works
Upvotes: 0
Reputation: 141
This is because shared data is NOT
synchronized.
To resolve this problem, use synchronized
on methods those touch the shared data
, to make Accum class Thread-Safe
.
example:
class Accum{
private static Accum a = new Accum();
private int counter = 0;
private Accum() {
}
public static Accum getAccum() {
return a;
}
public synchronized void updateCounter(int add) {
counter +=add;
}
public synchronized int getCount() {
return counter;
}
}
Upvotes: 3