原子/易失性/同步如何在内部工作?
以下代码块之间有什么区别?
代码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 …
说这static意味着所有对象的值的volatile一个副本并且意味着所有线程的值的一个副本是否正确?
无论如何,static变量值也将成为所有线程的一个值,那么我们为什么要这样做volatile呢?
读取和写入单个变量是原子的(语言保证!),除非变量的类型为long或double.
我正在读一个课程的幻灯片,我发现写了.这个类是关于并发的.
任何人都可以向我解释为什么写长或双不是原子操作?这让我感到惊讶.
Java 内存可见性文档说:
在每次后续读取同一字段之前,会发生对易失性字段的写入.
我很困惑多线程背景下的后续意义.这句话是否意味着所有处理器和内核都有一些全局时钟.那么例如我在某个线程的循环c1中为变量赋值,然后第二个线程能够在后续循环c1 + 1中看到该值?
关于内存可见性的小问题.
CodeSample1:
class CustomLock {
private boolean locked = false;
public boolean lock() {
if(!locked) {
locked = true;
return true;
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
此代码在多线程环境中容易出错,首先是因为"if-then-act"不是原子的,其次是因为潜在的内存可见性问题,例如threadA将字段设置为true,但是threadB是后来希望读取该字段的值可能看不到,仍然看到值false.
最简单的解决方案是使用synchronized关键字,如CodeSample2中所示.
CodeSample2:
class CustomLock {
private boolean locked = false;
public synchronized boolean lock() {
if(!locked) {
locked = true;
return true;
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
现在如果我希望使用原子变量,例如,AtomicBoolean(问题适用于所有原子变量),
CodeSample3:
public static class CustomLock {
private AtomicBoolean locked = new AtomicBoolean(false);
public boolean lock() {
return locked.compareAndSet(false, true);
}
}
Run Code Online (Sandbox Code Playgroud)
除了更好的性能考虑之外,我们可以看到现在我们使用AtomicBoolean 实现了与CodeSample1的"if-then-act"类似的逻辑.逻辑上代码的作用并不重要, …
无论有没有volatile关键字,我都会得到相同的输出。
我在代码中犯了错误吗?
public class MutliThreadExample extends Thread{
volatile int value;
public static void main(String[] args) throws InterruptedException {
MutliThreadExample thread1 = new MutliThreadExample();
MutliThreadExample thread2 = new MutliThreadExample();
thread1.start();
thread1.join();
thread2.start();
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
value = value + 1;
System.out.println(value + "-" + Thread.currentThread());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我无法volatile在 Java 中正确使用关键字。