如何在 Java 中运行类的不同实例的线程之间同步静态变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2120248/
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
How to synchronize a static variable among threads running different instances of a class in Java?
提问by Anonymous
I know that using the synchronize
keyword before a method brings synchronization to that object. That is, 2 threads running the same instance of the object will be synchronized.
我知道synchronize
在方法之前使用关键字为该对象带来同步。也就是说,运行同一对象实例的 2 个线程将被同步。
However, since the synchronization is at the object level, 2 threads running different instances of the object will not be synchronized. If we have a static variable in a Java class that is called by the method, we would like it to be synchronized across instances of the class. The two instances are running in 2 different threads.
但是,由于同步是在对象级别,因此运行对象的不同实例的 2 个线程将不会同步。如果我们在方法调用的 Java 类中有一个静态变量,我们希望它在类的实例之间同步。这两个实例在 2 个不同的线程中运行。
Can we achieve synchronization in the following way?
我们可以通过以下方式实现同步吗?
public class Test
{
private static int count = 0;
private static final Object lock= new Object();
public synchronized void foo()
{
synchronized(lock)
{
count++;
}
}
}
Is it true that since we have defined an object lock
that is static and we are using the keyword synchronized
for that lock, the static variable count
is now synchronized across instances of class Test
?
是不是因为我们已经定义了一个lock
静态对象并且我们使用了synchronized
该锁的关键字,那么静态变量count
现在在 class 的实例之间同步Test
?
采纳答案by Darron
There are several ways to synchronize access to a static variable.
有几种方法可以同步对静态变量的访问。
Use a synchronized static method. This synchronizes on the class object.
public class Test { private static int count = 0; public static synchronized void incrementCount() { count++; } }
Explicitly synchronize on the class object.
public class Test { private static int count = 0; public void incrementCount() { synchronized (Test.class) { count++; } } }
Synchronize on some other static object.
public class Test { private static int count = 0; private static final Object countLock = new Object(); public void incrementCount() { synchronized (countLock) { count++; } } }
使用同步静态方法。这在类对象上同步。
public class Test { private static int count = 0; public static synchronized void incrementCount() { count++; } }
在类对象上显式同步。
public class Test { private static int count = 0; public void incrementCount() { synchronized (Test.class) { count++; } } }
同步其他一些静态对象。
public class Test { private static int count = 0; private static final Object countLock = new Object(); public void incrementCount() { synchronized (countLock) { count++; } } }
Method 3 is the best in many cases because the lock object is not exposed outside of your class.
方法 3 在许多情况下是最好的,因为锁对象不会暴露在您的类之外。
回答by richs
Yes it is true.
是的,它是真的。
If you create two instance of your class
如果您创建类的两个实例
Test t1 = new Test();
Test t2 = new Test();
Then t1.foo and t2.foo both synchronize on the same static object and hence block each other.
然后 t1.foo 和 t2.foo 都在同一个静态对象上同步,因此相互阻塞。
回答by Kevin
If you're simply sharing a counter, consider using an AtomicIntegeror another suitable class from the java.util.concurrent.atomic package:
如果您只是共享一个计数器,请考虑使用AtomicInteger或 java.util.concurrent.atomic 包中的其他合适的类:
public class Test {
private final static AtomicInteger count = new AtomicInteger(0);
public void foo() {
count.incrementAndGet();
}
}
回答by Jafar Ali
You can synchronize your code over the class. That would be simplest.
您可以在类上同步您的代码。那将是最简单的。
public class Test
{
private static int count = 0;
private static final Object lock= new Object();
public synchronized void foo()
{
synchronized(Test.class)
{
count++;
}
}
}
Hope you find this answer useful.
希望你觉得这个答案有用。