假设一个类有一个public int counter
由多个线程访问的字段.这int
只是递增或递减.
要增加此字段,应使用哪种方法,为什么?
lock(this.locker) this.counter++;
,Interlocked.Increment(ref this.counter);
,counter
为public volatile
.现在,我发现volatile
,我已经删除了许多lock
语句和使用Interlocked
.但是有理由不这样做吗?
在今天的工作中,我遇到了volatile
Java中的关键字.我不太熟悉它,我发现了这个解释:
鉴于该文章解释了相关关键字的详细信息,您是否使用过它,或者您是否曾经看到过以正确方式使用此关键字的情况?
可能重复:
C++:什么时候有挥发性关键字帮你?
我从来没有用过它,但我想知道为什么人们会用它?它到底是做什么的?我搜索了论坛,发现它只是C#或Java主题.
原子/易失性/同步如何在内部工作?
以下代码块之间有什么区别?
代码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
呢?
AtomicBoolean做什么,一个volatile布尔无法实现?
我想知道在声明变量as volatile
和始终访问synchronized(this)
Java 中的块中的变量之间的区别?
根据这篇文章,http://www.javamex.com/tutorials/synchronization_volatile.shtml有很多要说的,但也有很多不同之处,但也有一些相似之处.
我对这条信息特别感兴趣:
...
- 对volatile变量的访问永远不会阻塞:我们只进行简单的读或写操作,因此与synchronized块不同,我们永远不会持有任何锁;
- 因为访问volatile变量永远不会持有锁,所以它不适合我们想要读取update-write作为原子操作的情况(除非我们准备"错过更新");
read-update-write是什么意思?写入也不是更新,还是仅仅意味着更新是依赖于读取的写入?
最重要的是,何时更适合声明变量volatile
而不是通过synchronized
块访问变量?使用volatile
依赖于输入的变量是一个好主意吗?例如,有一个变量被称为render
通过渲染循环读取并由按键事件设置?
正如我最近发布的这个答案所示,我似乎对volatile
多线程编程环境中的实用程序(或缺乏实用程序)感到困惑.
我的理解是这样的:每当一个变量可以在访问它的一段代码的控制流之外被改变时,该变量应该被声明为volatile
.信号处理程序,I/O寄存器和由另一个线程修改的变量都构成这种情况.
所以,如果你有一个全局int foo
,并且foo
由一个线程读取并由另一个线程原子设置(可能使用适当的机器指令),则读取线程看到这种情况的方式与它看到由信号处理程序调整的变量或由外部硬件条件修改,因此foo
应该声明volatile
(或者,对于多线程情况,使用内存隔离负载访问,这可能是一个更好的解决方案).
我怎么错,哪里错了?
volatile ×10
java ×5
c++ ×3
c ×2
c++-faq ×2
concurrency ×2
atomic ×1
boolean ×1
c# ×1
declaration ×1
interlocked ×1
java-me ×1
keyword ×1
locking ×1
static ×1
synchronized ×1