易失性关键字 - 它是跨线程保护值的唯一方法吗?

时间:2015-04-06 18:39:32

标签: java volatile

在Java中,volatile关键字用于直接从主内存读取和写入,以便在多个线程访问变量时不会丢失读取或写入。

不使用volatile,还有其他方法可以实现此功能吗?我遇到了这个问题,但无法找到解决方案。

2 个答案:

答案 0 :(得分:1)

基本上,如果要从多个线程安全地访问非易失性变量,则需要使用共享监视器的synchronized块包围对变量的所有读/写访问。无需同步对volatile变量(通常)的读访问权,因为每个读操作都可以保证看到任何线程对变量的最后一次写操作。

重要的是要注意,单独使用volatile字段并不能消除同步时的需要需要原子地读取变量的值,然后写入同一个变量。一个常见的用例是递增计数器。正如@Louis Wasserman建议的那样,出于这些目的,java.util.concurrent.atomic包中的类提供了可靠且易于使用的方法,例如compareAndSet(...)incrementAndGet()

答案 1 :(得分:1)

Java Language Specification描述了一组发生之前的关系,以及一组同步 - 操作。如果一个操作同步,则执行以下操作,之前发生。在此技术意义上,如果发生在读取之前,则保证可以看到写入。

synchronized块内执行的写入对于之后在该锁上同步的线程是可见的,因为释放锁与另一个线程的同步。

volatile变量的写入与该变量的后续读取同步 - ,因此它是可见的。

java.util.concurrent中的许多实用程序还提供发生在之前的关系。例如,线程在CountDownLatch上调用countDown()之前所采取的操作对于从该锁存器上的await()调用返回的线程是可见的。当然,其中许多API都是通过使用volatilesynchronized来实现的。