Java在两个线程之间共享一个变量

我有两个主题。 一个调用修改变量的类的update方法。 另一个调用读取变量的类的update方法。 只有一个线程写入,一个(或多个)线程读取该变量。 由于我不熟悉multithreading,因此在并发方面我需要做什么?

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... } } 

谢谢,

如果只有一个线程写入variable ,则可以使其变得volatile 。 否则,请使用AtomicInteger查看答案。

只有一个写入线程,只有volatile才能工作,因为只有一个写入线程,所以它始终具有正确的variable值。

在这种情况下,我将使用AtomicInteger ,但是通用的答案是对变量的访问应该由synchronized块保护,或者使用java.util.concurrent包的另一部分。

几个例子:

使用同步

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

使用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(); } } } 

variable不仅应该是volatile ,而且还希望通过某种同步保护update函数,因为++variable不是primefaces调用。 毕竟,这只是语法糖

 variable = variable + 1; 

这不是primefaces的。

您还应该将任何读取变量的调用包装在某种锁中。

或者,使用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... } } 

对于更复杂的算法,正如您最近的编辑所假设的那样,使用同步或锁定。

使用AtomicIntegersynchronize访问是安全的。