在Java中,volatile
关键字用于直接从主内存读取和写入,以便在多个线程访问变量时不会丢失读取或写入。
不使用volatile
,还有其他方法可以实现此功能吗?我遇到了这个问题,但无法找到解决方案。
答案 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都是通过使用volatile
,synchronized
来实现的。