java中多线程应用程序之间的易失成员

时间:2011-04-20 22:08:13

标签: java

如果两个线程同时尝试访问同一个volatile变量,会发生什么。在这种情况下什么类型的锁。 请帮我消除这个疑问。

4 个答案:

答案 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字段时没有锁定。忽略两个线程正在读取字段的无趣情况(扰流板:它们看到相同的值)我们有两种情况:

  1. 一个线程读取,另一个更新:读者将看到旧值或新值,具体取决于操作系统调度两个线程的顺序
  2. 两个线程都更新:该字段最终将保留最近安排的任何线程的值
  3. 重要的是要注意:

    • 即使字段属于long类型,占用8个字节的内存,JLS也保证,对于volatile个字段,读者永远不会看到(例如)4个字节的“旧” “新”的值和4个字节 - 它是全有或全无
    • 更新后计划的
    • 所有主题会立即看到新值

    对于非volatile字段,这些都不一定正确。

答案 3 :(得分:0)

大多数变量写入都是原子的,但volatile会确保在另一个线程尝试访问它之前将值写入内存区域,并确保线程不会为变速缓存变量(上下文切换可以是昂贵的,所以口译员可能会假设一些事情来获得速度)。如果未指定volatile,则可能是两个不同的线程在任何时候都可能具有不同的变量值,这可能会严重搞乱。

这是一本很好的读物:http://expertdevelopers.blogspot.com/2011/03/atomicity-thread-safety-in-java.html