Java定义了两类有趣的修饰符:transient和volatile。
1、 transient此为java保留字,告诉JVM以transient宣告的基本型态(primitive type)或物件(object)变量不要序列化,例如敏感性的数据像密码等。
如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。例如:
class Test {
transient int a; // 不会被持久化
int b; // 持久化
}
当类Test的实例对象被序列化(比如将Test类的实例对象 t 写入硬盘的文本文件t.txt中),变量 a 的内容不会被保存,变量 b 的内容则会被保存。
2、volatile用更低的代价替代同步(synchronized)。
为什么使用volatile比同步代价更低?
同步的代价,主要由其覆盖范围决定,如果可以降低同步的覆盖范围,则可以大幅提升程序性能。而volatile的覆盖范围仅仅变量级别的,因此它的同步代价很低。
volatile的工作原理:
volatile的语义,其实是告诉处理器,不要将我放入工作内存,请直接在主存操作我。因此,当多核或多线程在访问该变量时,都将直接操作主存,这从本质上,做到了变量共享。
参考:
把一个对象的表示转化为字节流的过程称为串行化(也称为序列化,serialization),从字节流中把对象重建出来称为反串行化(也称为为反序列化,deserialization)。transient 为不应被串行化的数据提供了一个语言级的标记数据方法。
volatile
volatile也是变量修饰符,只能用来修饰变量。volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
在此解释一下Java的内存机制:
Java使用一个主内存来保存变量当前值,而每个线程则有其独立的工作内存。线程访问变量的时候会将变量的值拷贝到自己的工作内存中,这样,当线程对自己工作内存中的变量进行操作之后,就造成了工作内存中的变量拷贝的值与主内存中的变量值不同。
Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。
分享到:
相关推荐
abstract - 1 - boolean - 2 - break - 2 - byte - 2 - case - 3 - catch - 3 - char - 4 - class - 4 - continue - 5 - ...transient - 17 - try - 17 - true - 18 - void - 18 - volatile - 18 - while - 18 -
1)transient和volatile是java关键字吗?(瞬联) 2)抽象类和接口有什么区别?(瞬联) 3)能说一下java的反射机制吗?(瞬联) 4)在java中怎样实现多线程?(瞬联) 5)你用过哪种设计模式?(瞬联,IBM,...
Java中的transient和volatile变量有什么区别? 提及同步块的用途 基于散列的集合中加载因子的默认大小是多少? 编写代码使集合只读? 区分谓词和函数? Java8中的Nashorn是什么? JVM 分配了多少种内存区域? 定义为...
1)transient和volatile是java关键字吗?(瞬联) 2)抽象类和接口有什么区别?(瞬联) 3)能说一下java的反射机制吗?(瞬联) 4)在java中怎样实现多线程?(瞬联) 5)你用过哪种设计模式?(瞬联,IBM,...
Q0040 Java关键字 "51个:abstract, boolean, break, byte, case, catch, char, class, const, continue, default, do, double, else, extends, final, finally, float, for, goto, if, implements, import, ...
java关键字 abstract do implement private this boolean double import protected throw break else instanceof public throws byte extends int return transient case false interface short true catch final ...
在 java 语言中,Java 程序的基本单位是类,也就是说:一个 Java 程序是由多个类组成 的。定义一个类与定义一个数据类型是有区别的。在程序设计语言中,把定义数据类型的能 力作为一种很重要的能力来对待。在面向...
B) 在Java中布尔类型不能和数字之间不能来回转换,即false和true不对应任何零或非零的值。 C) 双精度类型double比单精度类型float具有更高的精度和更大的表示范围,但float类型具有速度快、占用内存小的优点。 D) 在...
进行高精度运算可以用java.math包中BigDecimal类中的方法。 自动类型提升又称作隐式类型转换。 强制类型转换:int ti; (byte) ti ; 强制转换,丢弃高位 宣告变量名称的同时,加上“final”关键词来限定,这个...
目前先暂列目录,内容在逐渐增加中 JAVA 关键字 void byte int long char short float double String StringBuffer StringBuilder Array Collection Collections List ArrayList LinkedList Vector Set HashMap ...
【基础】Java 中的final关键字有哪些用法? 31 【基础】内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制? 31 【基础】I/O总结 31 【基础】Java中如何实现序列化,有什么意义? 34 【WEB】session与...
关键字 void byte int long char short float double String StringBuffer StringBuilder Array Collection Collections List ArrayList LinkedList Vector Set HashMap TreeMap LinkedHashMap ConcerrentHashMap ...
socket通信的拆包和装包源码 程序设计经验总结 一名JAVA程序员,将自己的编程学习之路做以总结并进行分享。内容包括但不限于数据结构、算法、数据库、操作系统、计算机网络等多方面。 目前先暂列目录,内容在逐渐...
25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................
•和类定义不同,定义接口不再用class关键字,而是使用interface关键字。语法如下: •[修饰符] interface接口名 extends 父接口1,父接口2 ... •{ • 零个到多个常量定义... • 零个到多个抽象方法定义... • ...