相关疑难解决方法(0)

atomic/volatile/synchronized有什么区别?

原子/易失性/同步如何在内部工作?

以下代码块之间有什么区别?

代码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 …

java multithreading synchronization atomic volatile

282
推荐指数
4
解决办法
13万
查看次数

Java内存模型:volatile变量和之前发生的

我想澄清一下,在关系与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 = 2
  • v = 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

36
推荐指数
3
解决办法
2367
查看次数

Java VM上的内存障碍和编码风格

假设我有一个静态复杂对象,它由一个线程池定期更新,并在一个长时间运行的线程中或多或少地连续读取.对象本身总是不可变的,反映了最近的某种状态.

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版本的奖励荣誉:)

java concurrency scala

26
推荐指数
1
解决办法
6566
查看次数