4

How can I access static variable from many thread simultaneously.

If I have a class like

Class A {
    public static boolean FLG=false;
    .....................
    ....................
}

And I need to access the value from thread 1 like

....................
public void run() {
    boolean t1=A.FLG;
    ..................
}

and from thread 2 I need to set value like

....................
public void run() {
    A.FLG=true;
    ..................
}

Does this cause memory violation ?. If so what is the recommended method to handle such a situation?.

Jonik
  • 80,077
  • 70
  • 264
  • 372
Haris
  • 13,645
  • 12
  • 90
  • 121

5 Answers5

5

If all you want to do is get and set a primitive you can make it volatile and it will be thread safe for those operations.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • I need to access the value as well as set the value – Haris Aug 28 '13 at 12:11
  • Hmm, interesting. I think it's true that ["the `volatile` keyword in Java is poorly documented, poorly understood, and rarely used"](http://www.javamex.com/tutorials/synchronization_volatile.shtml). Anyway, [looks like](http://stackoverflow.com/a/7943472/56285) `volatile` is not completely equivalent to making the accessors to the field `synchronized`. – Jonik Aug 28 '13 at 12:14
4

Wrap the static variable in a synchronized method and call the method as you like

public static synchronized void method1(){
//Whatever
}

public static synchronized void method2(){
//Whatever again
}

Note that there are other ways to synchronize access to a method. They are considered more efficient in environments busy threads accessing the same methods.

Check the ReentrantLock class. There are also answers for when to use synchronized and RentrantLock and many more information that could be found through google.

Also as peter's answer and muel's comment suggests. Marking the boolean variable as volatile should be helpful. volatile boolean variables will NOT cache it's initial value (false or true). The JVM could do that occasionally which could be unexpected by the programmer.

Community
  • 1
  • 1
Muhammad Gelbana
  • 3,890
  • 3
  • 43
  • 81
  • 2
    Why not just use volatile? – Muel Aug 28 '13 at 12:05
  • If the variable is used exactly as it can be seen in the code sample. The field can even be totally unprotected. Thread 2 will set its value, and Thread 1 will eventually see that change. If reading stale values is acceptable, `volatile` can be omitted, as writes to booleans are atomic on 32 bit platforms. – Giulio Franco Aug 28 '13 at 16:55
  • Which code sample do you mean ? `Thread 2...that change`: What do you mean ? – Muhammad Gelbana Aug 28 '13 at 17:46
1

In Class A , you can create a set and get method for FLG like:

public static synchronized boolean getFlag()
{
return FLG;
}

public static synchronized setFlag(boolean flag)
{
FLG=flag;
}

Now from other Threads, access value of FLG usng this method. This will keep the value of FLG Consistent across multiple Threads.

Nargis
  • 4,687
  • 1
  • 28
  • 45
1

You may get some undesired situation where two threads try to set different values into the static variable and you won`t have sure what exactly value really is there. The best way (thinking in a simple scenario) I think it is using AtomicBoolean ( http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html ) and you get the value in the object and use it (instead of using the object all the time, due a different thread can change it and you might get unexpected scenario).

Another suggestion is to use Byteman to create concurrent tests.

Regards, Luan

lcestari
  • 178
  • 5
0

If you do not want to use synchronized, ReentrantLock, you can write your own logic for this.

Example:

public class A extends Thread{

    public static boolean FLG=false;

    public A(String threadName) {
        start();
        setName(threadName);
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            if(this.getName().equals("getterThread") && FLG == true){
                boolean t1=A.FLG;
            }
            if(this.getName().equals("setterThread") && FLG == false){
                A.FLG = true;
            }
        }

    }

    public static void main(String[] args) {

        A dad = new A("getterThread");
        A son = new A("setterThread");
    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Amaldev
  • 983
  • 8
  • 10