Dav*_*ave 17 java concurrency multithreading
我有两个主题.一个调用修改变量的类的update方法.另一个调用读取变量的类的update方法.只有一个线程写入,一个(或多个)线程读取该变量.由于我不熟悉多线程,因此我需要在并发性方面做些什么?
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...
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢,
hid*_*isk 17
如果有一个且只有一个写入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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
不仅variable如此volatile,而且您还希望通过某种同步保护您的update函数,因为它不是原子调用.毕竟,它只是语法糖++variable
variable = variable + 1;
Run Code Online (Sandbox Code Playgroud)
这不是原子的.
您还应该将任何读取变量的调用包装在某种锁中.
或者,使用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...
}
}
Run Code Online (Sandbox Code Playgroud)
对于更复杂的算法,如您最近的编辑所假设,使用同步或锁定.