Java 在两个线程之间共享一个变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3493752/
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 share a variable between two threads
提问by Dave
I have two threads. One invokes the update method of a class that modifies a variable. Another invokes the update method of a class that reads the variable. Only one thread writes and one (or more) threads read that variable. What do I need to do in terms of concurrency, since I am new to multi-threading?
我有两个线程。一种是调用修改变量的类的更新方法。另一个调用读取变量的类的更新方法。只有一个线程写入,一个(或多个)线程读取该变量。由于我是多线程新手,我需要在并发方面做什么?
public class A
{
public int variable; // Does this need to be volatile?
// Not only int, could also be boolean or float.
public void update()
{
// Called by one thread constantly
++variable;
// Or some other algorithm
variable = complexAlgorithm();
}
}
public class B
{
public A a;
public void update()
{
// Called by another thread constantly
// I don't care about missing an update
int v = a.variable;
// Do algorithm with v...
}
}
Thanks,
谢谢,
采纳答案by hidralisk
If there is one and only one thread that writes to variableyou can get away with making it volatile. Otherwise see the answer with AtomicInteger.
Only volatilewill work in case of only one writing thread because there is only one writing thread so it always has the right value of variable.
如果只有一个线程向variable您写信,您就可以避免使用它volatile。否则请参阅答案AtomicInteger。
仅volatile在只有一个写入线程的情况下才有效,因为只有一个写入线程,因此它始终具有正确的 值variable。
回答by justkt
Not only should variablebe volatile, but you also want to protect your updatefunction with some sort of synchronizationsince ++variableis not an atomic call. It is, after all, just syntactic sugar for
不仅应该variable是volatile,而且您还希望通过某种同步来保护您的update功能,因为它不是原子调用。毕竟,它只是语法糖++variable
variable = variable + 1;
which is not atomic.
这不是原子的。
You should also wrap any calls that read variable in a lockof some sort.
您还应该将任何读取变量的调用包装在某种锁中。
Alternatively, use an AtomicInteger. It was made for this sort of thing (for just integer operations).
或者,使用AtomicInteger。它是为这种事情而制作的(仅用于整数运算)。
public class A
{
// initially had said volatile wouldn't affect this variable because
// it is not a primitive, but see correction in comments
public final AtomicInteger variable; // see comments on this issue of why final
public void update()
{
// Called by one thread constantly
variable.getAndIncrement(); // atomically adds one
}
public int retrieveValue()
{
return variable.get(); // gets the current int value safely
}
}
public class B
{
public A a;
public void update()
{
// Called by another thread constantly
int v = a.retrieveValue();
// Do algorithm with v...
}
}
For the more complex algorithms, as your recent edit assumes, use synchronization or locks.
对于更复杂的算法,正如您最近的编辑所假设的那样,请使用同步或锁。
回答by Jon Freedman
In this case I would use an AtomicInteger, however the generalised answer is that access to variable should be protected by a synchronized block, or by using another part of the java.util.concurrent package.
在这种情况下,我将使用AtomicInteger,但是一般的答案是对变量的访问应该受到同步块的保护,或者通过使用 java.util.concurrent 包的另一部分来保护。
A couple of examples:
几个例子:
Using synchronized
使用同步
public class A {
public final Object variable;
public void update() {
synchronized(variable) {
variable.complexAlgorithm();
}
}
}
public class B {
public A a;
public void update() {
sychronized(a.variable) {
consume(a.variable);
}
}
}
Using java.util.concurrent
使用 java.util.concurrent
public class A {
public final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public final Object variable;
public void update() {
lock.writeLock().lock();
try {
variable.complexAlgorithm();
} finally {
lock.writeLock().unlock();
}
}
}
public class B {
public A a;
public void update() {
a.lock.readLock().lock();
try {
consume(a.variable);
} finally {
a.lock.readLock().unlock();
}
}
}
回答by b_erb
Use AtomicIntegeror synchronizethe access to be safe.
使用AtomicInteger或synchronize访问是安全的。

