【问题标题】:What are Transient and Volatile Modifiers?什么是瞬态和易失性修饰符?
【发布时间】:2011-04-02 11:24:55
【问题描述】:

有人能解释一下transientvolatile 修饰符在Java 中的含义吗?

【问题讨论】:

标签: java serialization storage modifier


【解决方案1】:

volatiletransient 修饰符可以应用于类1 的字段,而与字段类型无关。除此之外,它们是无关的。

transient 修饰符告诉 Java 对象序列化子系统在序列化类的实例时排除该字段。当对象被反序列化时,该字段将被初始化为默认值;即null 用于引用类型,零或false 用于原始类型。请注意,JLS(参见8.3.1.3)没有说明transient 的含义,而是遵循Java Object Serialization Specification。其他序列化机制可能关注字段的transient-ness。或者他们可能会忽略它。

(请注意,JLS 允许将 static 字段声明为 transient。这种组合对于 Java 对象序列化没有意义,因为它无论如何都不会序列化静态。但是,在其他情况下,因此有一些理由不完全禁止它。)

volatile 修饰符告诉 JVM 对字段的写入应始终同步刷新到内存,而对字段的读取应始终从内存中读取2。这意味着标记为 volatile 的字段可以在多线程应用程序中安全地访问和更新,而无需使用本机或基于标准库的同步。同样,对 volatile 字段的读取和写入也是原子性的。 (这不适用于 >>non-volatilelong 或 double 字段,在某些 JVM 上可能会出现“单词撕裂”。) JLS 的相关部分是 8.3.1.417.417.7


1 - 但不是局部变量或参数。
2 - 这种解释是故意不正式的。有关volatile 语义的精确、正式、详细的规范,请参阅上面链接的 JLS 第 17 章(内存模型)参考资料。请注意,JMM 规范是针对建模行为而言的,并且不知道该行为是如何在平台级别实现的。

【讨论】:

    【解决方案2】:

    瞬态:

    首先需要知道它需要如何弥合差距。

    1) 访问修饰符瞬态仅适用于可变组件。 它不会与方法或类一起使用。

    2) 瞬态关键字不能与静态关键字一起使用。

    3) 什么是序列化以及它在哪里使用? 序列化是使对象的状态持久化的过程。这意味着对象的状态被转换为字节流以用于持久化(例如,将字节存储在文件中)或传输(例如,通过网络发送字节)。同样,我们可以使用反序列化从字节中恢复对象的状态。这是 Java 编程中的重要概念之一,因为序列化主要用于网络编程。需要通过网络传输的对象必须转换为字节。 在了解瞬态关键字之前,必须了解序列化的概念。如果读者对序列化有所了解,请跳过第一点。

    注 1) Transient 主要用于序列化过程。 为此,该类必须实现 java.io.Serializable 接口。 类中的所有字段都必须是可序列化的。如果字段不可序列化,则必须将其标记为瞬态。

    注意 2) 当反序列化过程发生时,它们会根据类型约束设置为默认值 - 零、假或 null。

    注3)瞬态关键字及其用途? 使用瞬态修饰符声明的字段将不参与序列化过程。 当一个对象被序列化(以任何状态保存)时,其瞬态字段的值在序列表示中被忽略,而瞬态字段以外的字段将参与序列化过程。这就是transient关键字的主要用途。

    【讨论】:

    • 这应该是最高票的!很好的解释。
    • 吹毛求疵:transientvolatile 都不是 access 修饰符。访问修饰符是publicprotectedprivate
    【解决方案3】:

    volatiletransient 关键字

    1) transient 关键字与实例变量一起使用以将它们从序列化过程中排除。如果一个字段是transient,它的值将不会被持久化。

    另一方面,volatile 关键字用于将 Java 变量标记为“正在存储在主内存中”。

    volatile 变量的每次读取都将从计算机的主内存中读取,而不是从 CPU 缓存中读取,并且对volatile 变量的每次写入都将写入主内存,而不仅仅是 CPU缓存。

    2) transient 关键字不能与static 关键字一起使用,但volatile 可以与static 一起使用。

    3) transient 变量在反序列化过程中被初始化为默认值,并且值的赋值或恢复必须由应用程序代码处理。

    更多信息请看我的博客:
    http://javaexplorer03.blogspot.in/2015/07/difference-between-volatile-and.html

    【讨论】:

    • transient 变量不能与static 关键字一起使用的原因是静态变量属于一个类而不属于任何单个实例。序列化的概念与对象的当前状态有关。只有与类的特定实例关联的数据才会被序列化,因此在序列化过程中会忽略静态成员字段
    • 其实JLS允许statictransient一起使用。问题是它没有什么意义,因为典型的序列化机制无论如何都不会保持静态。
    【解决方案4】:

    Volatile 意味着其他线程可以编辑该特定变量。所以编译器允许访问它们。

    http://www.javamex.com/tutorials/synchronization_volatile.shtml

    瞬态意味着当你序列化一个对象时,它会在反序列化时返回它的默认值

    http://www.geekinterview.com/question_details/2

    【讨论】:

    • "所以编译器允许访问它们。"您的句子表明默认情况下线程没有访问权限。现在我阅读了链接和我理解的另一个答案:编译器不会对变量进行任何类型的线程特定中间存储,因此其他线程可以立即看到更改。
    • 我把 C 的使用 volatile 和 java 的使用 volatile 弄糊涂了。我的意思是编译器确保它可以访问字段的实际值而不是缓存值。
    猜你喜欢
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    • 2013-08-28
    • 2021-11-21
    • 2012-05-14
    • 1970-01-01
    相关资源
    最近更新 更多