Sultan Sultan - 2 months ago 7
Java Question

Setting and accessing a varibale by two different threads

I have two threads, one setting a variable of a class, and the other one accessing the variable by a get method.

public class Parent {
private int value = -1

public int getValue()
return this.value;
}

public void setValue(int value){
this.value = value;
}

private class UpdatingVaribale extends Thread {

public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
setValue(2);
Thread.currentThread().interrupt();
}
}
}
}

private class GettingVaribale extends Thread {

public void run() {
while (getValue == -1) {
try{
System.out.println(getValue);
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
System.out.println(getValue);
}
}


The problem is that the condition of the
while
loop in the second thread is always
true
. The
System.out.println(getValue)
always prints
-1
. I am wondering why the second thread doesn't get the new value of
value
which is
2
. I don't think the
synchronized
matters here since one thread is setting a variable and the other one just accessing the variable.

Answer

There are some solutions here:

  1. use standard Java class AtomicInteger for storing your value in multi-threaded safe way. Actually it's the best and fastest way.
  2. add synchronized keyword to your getValue and setValue methods
  3. add volatile java keyword to i field definition

The source of your problem is i variable value actually looks different in different threads cause of CPU speed and memory optimization and you have to specify JVM somehow don't to do this optimization and - opposite - makes the latest i value visible in all threads.

UPDATE code for testing

public class SyncProblem {

    public static void main(String[] args) {
        Parent parent = new Parent();
        new Thread(parent.new GettingVaribale()).start();
        new Thread(parent.new UpdatingVaribale()).start();
    }
}

class Parent {
    private volatile int value = -1;

    public int getValue() {
        return this.value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    class UpdatingVaribale implements Runnable {
        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                setValue(2);
                Thread.currentThread().interrupt();
            }
        }
    }

    class GettingVaribale implements Runnable {
        @Override
        public void run() {
            while (getValue() == -1) {
                try {
                    System.out.println(getValue());
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                }
            }
            System.out.println(getValue());
        }
    }
}
Comments