如何同时从多个线程访问静态变量。
如果我有类似
的课程Class A {
public static boolean FLG=false;
.....................
....................
}
我需要从线程1中访问值
....................
public void run() {
boolean t1=A.FLG;
..................
}
从线程2我需要设置像
这样的值....................
public void run() {
A.FLG=true;
..................
}
这会导致内存违规吗?如果是这样,处理这种情况的推荐方法是什么?
答案 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 缓存它的初始值(false
或true
)。 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");
}
}