【Java编程】volatile和transient关键字的理解
理解volatile
volatile是java提供的一种轻量级的同步机制,所谓轻量级,是相对于synchronized(重量级锁,开销比较大)而言的。
根据java虚拟机的内存模型,我们知道其中规定了:共享变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory),本地内存保存了被该线程使用到的主内存的副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。
所谓同步,可以用如下这段同步格言来理解:如果向一个变量写入值,而这个变量接下来很有可能会被另一个线程读取,或者,从一个变量读值,而这个变量很有可能是之前被另一个线程写入的,此时为了保证不发生错误,就必须保证同步。
当对非 volatile 变量进行读写的时候,每个线程先从内存拷贝变量到自己的缓存中。如果计算机有多个CPU,每个线程可能在不同的CPU上被处理,这意味着每个线程可以拷贝到不同的 cache 中。
而声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读,跳过 CPU cache 这一步。
因此,总结起来,volatile是一种轻量级的同步机制,它主要有两个特性:
一是保证共享变量对所有线程的可见性;所谓可见性,就是指当一个线程修改了这个共享变量的值,可以立即同步到主存,每次使用前从主存刷新。
二是禁止指令重排序优化。指令重排序时不能把后面的指令重排序到内存屏障之前的位置。
同时需要注意的是,volatile并不是可以完全保证同步的,它不具有原子性。对于单个的共享变量的读/写具有原子性,但是像num++这种复合操作,volatile无法保证其原子性。
在 Java 中 volatile、synchronized 和 final 实现可见性。
在 Java 中 synchronized 和在 lock、unlock 中操作保证原子性。
理解transient
一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。
有时,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。
总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
总结起来,就是以下三点:
(1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
(2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
(3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
【Java编程】volatile和transient关键字的理解的更多相关文章
- Java编程基础——标识符和关键字
Java编程基础——标识符和关键字 摘要:本文主要介绍标识符和关键字. 标识符 是什么 Java语言中,为各种变量.方法.类和包等起的名字,统统称之为Java标识符. 命名规则 ◆ 应以字母.下划线. ...
- Java transient关键字的理解
transient [ˈtrænziənt] adj. 短暂的; 转瞬即逝的; 临时的 n 临时旅客; 瞬变现象; 候鸟; 1. transient的作用及使用方法 我们都知道一个对象只要 ...
- K:java序列化与反序列化—transient关键字的使用
首先,应该明白的是transient是java中的一个关键字,音标为 英: [ˈtrænziənt]. 在了解transient关键字之前,应该先弄明白序列化和反序列化.所谓的序列化,通俗点的 ...
- transient关键字的理解
谈到这个transient这个关键字,我们应该会立马想到序列化这个过程:什么是序列化?什么又是反序列化呢?序列化就是将对象转化内成二进制,而反序列化就是就二进制文件转换成对象的过程.一旦变量使用了tr ...
- java volatile 和Transient 关键字
java关键字volatile volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变化值回写到主内存.这样在任何时刻,两个不同 ...
- (五)《Java编程思想》——final关键字
可能使用final的三种情况:数据.方法.类. 1.final数据 final 常量必须是基本类型数据,且在定义时须赋值: 一个既是static又是final的域只占据一段不能改变的存储空间,只有一份 ...
- java基础篇 之 super关键字的理解
之前一直认为,super指向的是父类对象.到今天,仔细查询了资料,自己做了实验,确认这个结论是不对的.我们分一下几个点讨论下: super的作用: 第一种:用来访问父类被隐藏的成员变量 第二种:用 ...
- Java并发专题(三)深入理解volatile关键字
前言 上一章节简单介绍了线程安全以及最基础的保证线程安全的方法,建议大家手敲代码去体会.这一章会提到volatile关键字,虽然看起来很简单,但是想彻底搞清楚需要具备JMM.CPU缓存模型的知识.不要 ...
- java中的transient关键字详解
目录 1.何谓序列化? 2.为何要序列化? 3.序列化与transient的使用 4.java类中serialVersionUID作用 5.transient关键字小结 前言 说实话学了一段时间jav ...
随机推荐
- maven知识总结
使用maven中的命令运行web项目 以上为web项目的目录结构 必须是maven项目 启动命令行 使用 mvn tomcat:run 敲击回车 访问红框中的地址: 关闭命令行 那么项目就 ...
- orcale 日期显示格式化
SQL> select * 2 from emp 3 where hiredate='1987-11-17'; where hiredate='1987-11-17' * 第 3 行出现错误: ...
- HDU - 4323 - Magic Number
先上题目: Magic Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- 反射常用API
反射所有功能都是通过class API来实现的 class常用API有: 1.class.GETINTERFACES():获得这个类实现的接口. 2.class.getMethods() Method ...
- Android ORM——初识greenDAO 3及使用greenDAO 3前应该掌握的一些知识点(一)
引言 总所周知,SQLite--内嵌于Android中一个占用内存极小的关系型,作为我们Android存储领域中重要的一员 ,或多或少都曾接触到数据库.即使Android系统中提供了很多操作SQLit ...
- SecureCRT图形界面(通过设置调用Xmanager - Passive程序)
首先,在server进行设置 假设server是图形化界面启动的,xhost +命令能够不用运行 [root@test ~]# xhost + xhost: unable to open displ ...
- 单片机小白学步系列(十四) 点亮第一个LED的程序分析
本篇我们将分析上一篇所写的程序代码.未来学习单片机的大部分精力,我们也将放在程序代码的编写上. 可是不用操心.我会很具体的介绍每一个程序的编写思路和各种注意事项等. 之前我们写的程序例如以下: #in ...
- Epos消费管理系统复制迁移SQL SERVER 2005数据库
先脱机 原来要关闭Epos消费管理系统软件才可以让对应的数据库脱机
- MyBatis输出执行的SQL到控制台
src\main\resources\application.properties 或者src\main\resources\application.yml 在你的application.proper ...
- VirtualBox 5.1.14 获取VirtualBox COM对象错误
Oracle VM VirtualBox 5.1.14 安装完成之后显示错误, Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, but C ...