Java多线程访问静态变量

时间:2013-08-28 11:59:52

标签: java multithreading static

如何同时从多个线程访问静态变量。

如果我有类似

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

我需要从线程1中访问值

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

从线程2我需要设置像

这样的值
....................
public void run() {
    A.FLG=true;
    ..................
}

这会导致内存违规吗?如果是这样,处理这种情况的推荐方法是什么?

5 个答案:

答案 0 :(得分:3)

在同步方法中包装静态变量并根据需要调用方法

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

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

请注意,还有其他方法可以同步对方法的访问。在繁忙线程访问相同方法的环境中,它们被认为更有效。

检查ReentrantLock课程。还有when to use synchronized and RentrantLock的答案以及可以通过Google找到的更多信息。

另外,peter的回答和muel的评论也是如此。将boolean变量标记为volatile应该会有所帮助。 volatile布尔变量将 NOT 缓存它的初始值(falsetrue)。 JVM偶尔会这样做,这可能是程序员意想不到的。

答案 1 :(得分:3)

如果你想做的就是获取并设置一个原语,你就可以使它成为volatile,这对于那些操作来说是线程安全的。

答案 2 :(得分:1)

在A类中,您可以为FLG创建一个set和get方法,如:

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

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

现在来自其他线程,FLG的访问值使用此方法。这将保持FLG的值在多个线程中保持一致。

答案 3 :(得分:1)

你可能会遇到一些不希望出现的情况:两个线程试图将不同的值设置到静态变量中,你不确定那里究竟有什么值。最好的方法(在一个简单的场景中思考)我认为它是使用AtomicBoolean(http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html)并且您获得对象中的值并使用它(而不是一直使用该对象,因为不同的线程可以更改它可能会出现意外情况。)

另一个建议是使用Byteman创建并发测试。

此致 栾

答案 4 :(得分:0)

如果您不想使用synchronized,ReentrantLock, 你可以为此编写自己的逻辑。

示例:

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