如果两个线程同时尝试访问同一个volatile变量,会发生什么。在这种情况下什么类型的锁。 请帮我消除这个疑问。
答案 0 :(得分:4)
这可能会对你有所帮助:
我们在第二点说“好像”,因为至少对程序员来说(可能在大多数JVM实现中)没有涉及实际的锁对象。
来源:http://www.javamex.com/tutorials/synchronization_volatile.shtml
答案 1 :(得分:1)
我有一个short text snippet来解释易变量。
易失性变量不会缓存在寄存器或缓存中,而是隐藏在其他处理器中,因此读取volatile变量始终返回任何线程的最新写入。
然而访问volatile变量不执行锁定,因此不能导致执行线程阻塞,使得volatile变量的重量同步机制比同步更轻。
示例:
当线程A写入volatile时 变量和随后的线程B. 读取相同的变量,值 可见的所有变量 在写入volatile之前 变量在B之后变得可见 读取易变量。
答案 2 :(得分:1)
在单CPU机器上没有“同时” - 操作系统(OS)安排每个线程在短时间内执行,然后移动到下一个帖子。
在多CPU(SMP)计算机上,两个CPU可以同时执行代码,但Java Language Specification(JLS)提供有关volatile
字段的保证,因此您仍然可以编写正确的多线程代码。
从程序员的角度来看,处理volatile
字段时没有锁定。忽略两个线程正在读取字段的无趣情况(扰流板:它们看到相同的值)我们有两种情况:
重要的是要注意:
long
类型,占用8个字节的内存,JLS也保证,对于volatile
个字段,读者永远不会看到(例如)4个字节的“旧” “新”的值和4个字节 - 它是全有或全无对于非volatile
字段,这些都不一定正确。
答案 3 :(得分:0)
大多数变量写入都是原子的,但volatile会确保在另一个线程尝试访问它之前将值写入内存区域,并确保线程不会为变速缓存变量(上下文切换可以是昂贵的,所以口译员可能会假设一些事情来获得速度)。如果未指定volatile,则可能是两个不同的线程在任何时候都可能具有不同的变量值,这可能会严重搞乱。
这是一本很好的读物:http://expertdevelopers.blogspot.com/2011/03/atomicity-thread-safety-in-java.html