Java 多线程访问静态变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18487274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Multithread Access Static Variable
提问by Haris
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
我需要从线程 1 中访问值,例如
....................
public void run() {
boolean t1=A.FLG;
..................
}
and from thread 2 I need to set value like
从线程 2 我需要设置值
....................
public void run() {
A.FLG=true;
..................
}
Does this cause memory violation ?. If so what is the recommended method to handle such a situation?.
这会导致内存冲突吗?。如果是这样,处理这种情况的推荐方法是什么?
采纳答案by Muhammad Gelbana
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 ReentrantLockclass. There are also answers for when to use synchronized and RentrantLockand many more information that could be found through google.
检查ReentrantLock类。还有关于何时使用 synchronized 和 RentrantLock 的答案以及可以通过谷歌找到的更多信息。
Also as peter
's answer and muel
's comment suggests. Marking the boolean
variable as volatile should be helpful. volatile
boolean variables will NOTcache it's initial value (false
or true
). The JVM could do that occasionally which could be unexpected by the programmer.
也正如peter
's answer 和muel
's comment 所暗示的那样。将boolean
变量标记为 volatile 应该会有所帮助。volatile
布尔变量不会缓存它的初始值(false
或true
)。JVM 偶尔会这样做,这可能是程序员意想不到的。
回答by Peter Lawrey
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.
如果您想要做的只是获取和设置一个原语,您可以创建它,volatile
并且对于这些操作来说它将是线程安全的。
回答by Nargis
In Class A , you can create a set and get method for FLG like:
在 Class A 中,您可以为 FLG 创建一个 set 和 get 方法,例如:
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.
现在从其他线程,使用FLG
此方法访问值。这将FLG
在多个线程中保持 Consistent的值。
回答by lcestari
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).
您可能会遇到一些不希望出现的情况,即两个线程尝试将不同的值设置到静态变量中,而您将无法确定真正存在的值到底是什么。最好的方法(在一个简单的场景中思考)我认为它是使用 AtomicBoolean ( http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html) 并且你得到对象中的值并使用它(而不是一直使用该对象,因为不同的线程可以更改它,您可能会遇到意外情况)。
Another suggestion is to use Byteman to create concurrent tests.
另一个建议是使用 Byteman 创建并发测试。
Regards, Luan
问候,栾
回答by Amal
If you do not want to use synchronized, ReentrantLock, you can write your own logic for this.
如果不想使用synchronized、ReentrantLock,可以为此编写自己的逻辑。
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");
}
}