volatile能否用于多线程的数据同步(线程安全)?
答案是不能!!
以前网上很多资料说用volatile实现无锁,但这样是行不通的。
相关参考:
Why is volatile not considered useful in multithreaded C or C++ programming?
Stay away from Volatile in threaded code?
https://sites.google.com/site/kjellhedstrom2/stay-away-from-volatile-in-threaded-code
When to use volatile with multi threading?
http://stackoverflow.com/questions/4557979/when-to-use-volatile-with-multi-threading
Short & quick answer: volatile
is (nearly) useless for platform-agnostic, multithreaded application programming. It does not provide any synchronization, it does not create memory fences, nor does it ensure the order of execution of operations. It does not make operations atomic. It does not make your code magically thread safe. volatile
may be the single-most misunderstood facility in all of C++. See this, this and this for more information about volatile
On the other hand, volatile
does have some use that may not be so obvious. It can be used much in the same way one would use const
to help the compiler show you where you might be making a mistake in accessing some shared resource in a non-protected way. This use is discussed by Alexandrescu in this article. However, this is basically using the C++ type system in a way that is often viewed as a contrivance and can evoke Undefined Behavior.
volatile
was specifically intended to be used when interfacing with memory-mapped hardware, signal handlers and the setjmp machine code instruction. This makes volatile
directly applicable to systems-level programming rather than normal applications-level programming.
The 2003 C++ Standard does not say that volatile
applies any kind of Acquire or Release semantics on variables. In fact, the Standard is completely silent on all matters of multithreading. However, specific platforms do apply Acquire and Release semantics on volatile
variables.
[Update for C++11]
The C++11 Standard now does acknowledge multithreading directly in the memory model and the lanuage, and it provides library facilities to deal with it in a platform-independant way. However the semantics of volatile
still have not changed. volatile
is still not a synchronization mechanism. Bjarne Stroustrup says as much in TCPPPL4E:
Do not use
volatile
except in low-level code that deals directly with hardware.Do not assume
volatile
has special meaning in the memory model. It does not. It is not -- as in some later languages -- a synchronization mechanism. Sto get synchronization, useatomic
, amutex
, or acondition_variable
.
[/End update]
The above all applies the the C++ language itself, as defined by the 2003 Standard (and now the 2011 Standard). Some specific platforms however do add additional functionality or restrictions to what volatile
does. For example, in MSVC 2010 (at least) Acquire and Release semantics do apply to certain operations on volatile
variables. From the MSDN:
When optimizing, the compiler must maintain ordering among references to volatile objects as well as references to other global objects. In particular,
A write to a volatile object (volatile write) has Release semantics; a reference to a global or static object that occurs before a write to a volatile object in the instruction sequence will occur before that volatile write in the compiled binary.
A read of a volatile object (volatile read) has Acquire semantics; a reference to a global or static object that occurs after a read of volatile memory in the instruction sequence will occur after that volatile read in the compiled binary.
However, you might take note of the fact that if you follow the above link, there is some debate in the comments as to weather or not acquire/release semantics actually apply in this case.
相关推荐
在提供的"ScanThread"文件名中,我们可以推测这是一个扫描线程的实现,可能是用来定时或按需扫描数据源,然后触发数据同步的过程。可能包含了线程启动、同步机制、数据处理逻辑等内容。 综上所述,这个电信项目实例...
操作系统实验是计算机科学教育中的重要组成部分,它帮助学生理解和掌握操作系统的基本原理,特别是多线程同步与互斥的概念。在Java编程环境下,这些概念可以通过实际的代码实现来深入理解。 多线程是现代操作系统中...
而volatile确保了每次读取都是从主内存中获取最新值,写入时也会立即同步到主内存,从而保证了不同线程之间的数据同步。 其次,volatile还具有禁止指令重排序的效果,这关乎到程序的有序性。在多线程环境下,为了...
4. **谨慎使用**:虽然`volatile`提供了一种简单的方法来处理多线程环境中的共享变量,但它并不能解决所有的同步问题。在复杂的并发场景下,使用`volatile`可能不足以保证线程安全,需要结合其他的同步原语一起使用...
Java 多线程机制提供了两种实现同步的方式:Synchronized 和 Volatile。 1. Synchronized Synchronized 是 Java 语言中的一个关键字,用于实现线程同步。它可以保证在同一个时刻,只有一个线程可以执行某个方法...
Java多线程详解 在Java编程中,多线程是一种重要的技术...了解并熟练掌握这些知识点,你就能在实际开发中灵活运用Java的多线程特性,编写出高效、稳定的并发程序。通过实践和不断学习,你将成为一个多线程编程的专家。
《深入理解Volatile》 Volatile是C/C++编程语言中的一个关键字,它与const一起被称为"cv特性",用于指示变量的值可能被系统...但在使用时,需要注意其局限性,特别是在多线程环境下,volatile并不能完全替代同步机制。
在大型系统开发中,多线程技术使得程序能够同时执行多个任务,提高系统的并发性,而同步机制则确保了在多线程环境下数据的一致性和完整性。下面将对这两个关键知识点进行深入解析。 一、Java多线程 1. **线程创建...
volatile是C#中用于控制同步的关键字,其意义是针对程序中一些敏感数据,不允许多线程同时访问,保证数据在任何访问时刻,最多有一个线程访问,以保证数据的完整性,volatile是修饰变量的修饰符。 1、volatile的使用...
线程同步是 Java 编程中的一种机制,用于控制多个线程之间的资源访问顺序,以避免线程之间的冲突和数据不一致。线程同步的目的就是避免线程“同步”执行,即让多个线程之间排队操作共享资源。 关于线程同步,需要...
8. **异常处理**:在多线程环境中,每个线程都有自己的异常处理机制,主线程不能直接捕获子线程的异常。因此,必须在子线程内部进行适当的异常处理。 9. **线程局部存储**:`ThreadLocal<T>`类允许在线程中创建局部...
在多线程环境中,数据共享可能导致数据不一致,为了解决这个问题,Java提供了多种同步机制。包括: - **synchronized关键字**:用于方法或代码块,确保同一时间只有一个线程访问特定资源。 - **volatile关键字**...
同时,我们也应该注意到`volatile`并不能保证操作的原子性,因此在需要原子性操作时还需要考虑其他同步机制,如`synchronized`关键字或`java.util.concurrent`包中的高级同步工具类。在实际开发中灵活运用这些工具和...
Volatile关键字可以保证线程间变量的可见性,但不能保证原子性。在多线程环境下,如果一个变量被多个线程共享且只进行读写操作,可以使用volatile保证数据的一致性。 9. sleep(), yield(), interrupt(): - sleep...
其次,线程同步是多线程编程中的关键部分,以防止数据竞争和不一致。Java提供了多种同步机制,如synchronized关键字、Lock接口(如ReentrantLock)以及volatile关键字。synchronized用于控制对共享资源的访问,确保...
在多线程环境中,当多个线程同时访问和修改同一份共享资源时,如果没有合适的同步措施,可能会导致数据不一致、死锁或竞态条件等错误。为了解决这些问题,Java提供了同步机制。 2. **synchronized关键字** `...
Java多线程与同步是Java编程中的重要概念,它们在构建高效、响应迅速的应用程序时起着关键作用。本文将深入探讨Java中的多线程机制以及如何通过同步控制来确保线程安全。 首先,让我们理解什么是多线程。在单线程...
- volatile:修饰变量,确保多线程环境下的可见性和有序性,但不保证原子性。在实例中,可能用于共享标志的设置与读取。 - wait()、notify()和notifyAll():这些方法存在于Object类中,用于线程间的通信。在线程A...