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... } }
对于更复杂的算法,正如您最近的编辑所假设的那样,使用同步或锁定。
使用AtomicInteger
或synchronize
访问是安全的。