原子/易失性/同步如何在内部工作?
以下代码块之间有什么区别?
代码1
private int counter;
public int getNextUniqueIndex() {
return counter++;
}
Run Code Online (Sandbox Code Playgroud)
代码2
private AtomicInteger counter;
public int getNextUniqueIndex() {
return counter.getAndIncrement();
}
Run Code Online (Sandbox Code Playgroud)
代码3
private volatile int counter;
public int getNextUniqueIndex() {
return counter++;
}
Run Code Online (Sandbox Code Playgroud)
是否volatile以下列方式工作?是
volatile int i = 0;
void incIBy5() {
i += 5;
}
Run Code Online (Sandbox Code Playgroud)
相当于
Integer i = 5;
void incIBy5() {
int temp;
synchronized(i) { temp = i }
synchronized(i) { i = temp + 5 }
}
Run Code Online (Sandbox Code Playgroud)
我认为两个线程不能同时进入同步块...我是对的吗?如果这是真的那么如何atomic.incrementAndGet()工作没有synchronized …
我想澄清一下,在关系与volatile变量一起工作之前会发生什么.我们有以下变量:
public static int i, iDst, vDst;
public static volatile int v;
Run Code Online (Sandbox Code Playgroud)
和线程A:
i = 1;
v = 2;
Run Code Online (Sandbox Code Playgroud)
和线程B:
vDst = v;
iDst = i;
Run Code Online (Sandbox Code Playgroud)
以下语句是否符合Java内存模型(JMM)?如果没有,那么正确的解释是什么?
i = 1总是发生在以前 v = 2v = 2 发生 vDst = v在JMM 之前,只有它实际发生在时间之前i = 1 发生 iDst = i在JMM 之前(并且iDst可以预测分配1)如果v = 2实际发生vDst = v在时间之前i = 1和之间的顺序iDst …java volatile java-memory-model thread-synchronization happens-before
假设我有一个静态复杂对象,它由一个线程池定期更新,并在一个长时间运行的线程中或多或少地连续读取.对象本身总是不可变的,反映了最近的某种状态.
class Foo() { int a, b; }
static Foo theFoo;
void updateFoo(int newA, int newB) {
f = new Foo();
f.a = newA;
f.b = newB;
// HERE
theFoo = f;
}
void readFoo() {
Foo f = theFoo;
// use f...
}
Run Code Online (Sandbox Code Playgroud)
我至少不在乎我的读者是看到旧的还是新的Foo,但是我需要看到一个完全初始化的对象.IIUC,Java规范说没有HERE中的内存屏障,我可能会看到一个fb初始化但尚未提交到内存的对象.我的程序是一个真实世界的程序,它迟早会将内容提交到内存中,所以我不需要立即将新的值ofFoo提交到内存中(虽然它不会受到伤害).
您认为实现内存屏障最可读的方式是什么?如果需要,我愿意为了可读性而付出一点性能价格.我想我可以将赋值同步到Foo,这样可行,但是我不确定读取代码的人为什么这么做是非常明显的.我还可以同步新Foo的整个初始化,但这会引入更多实际需要的锁定.
你会如何编写它以使其尽可能可读?
对Scala版本的奖励荣誉:)