Java Multithread Access Static Variable

2019-03-30 08:08发布

问题:

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?.

回答1:

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.



回答2:

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.



回答3:

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



回答4:

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.



回答5:

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");
    }
}