Java中初级数值类型的大小, volatile和包装类wrapped type的比较
Java中的初级数值类型
Java是静态类型语言, 所有的变量必须先声明再使用. 其初级类型一共8种:
- boolean: 数据只包含1bit信息, 但是占空间为8-bit, 默认值为false
- byte: 8-bit 带符号补码型整数, 取值 -128 ~ 127. 使用于一些对内存空间敏感的大型数组.
- char: 16-bit单Unicode字符, 最小值也是默认值, 为'\u0000'(或0), 最大值为'\uFFFF'(或65,535).
- short: 16-bit 带符号补码型整数, 取值 -32,768 ~ 32,767, 用途同上
- int: 32-bit 带符号补码型整数, 取值 -231 ~ 231 - 1, 这个值是 2,147,483,648(约21.4亿). 自Java8开始, 可以使用int类型来表示一个无符号32-bit整数, 表示 0 ~ 232 的数值, 具体实现在Integer类中.
- long: 64-bit 带符号补码型整数, 取值 -263 ~ 263 - 1, 自Java8开始, 也可以通过long类型表示一个无符号64-bit整数, 具体实现在Long类中.
- float: 单精度32-bit IEEE754浮点数.
- double: 双精度64-bit IEEE754浮点数.
关于32位JVM和64位JVM
无论是32-bit JVM, 还是 64-bit JVM, 以上数值所占空间都是一样的. 在32位JVM和64位JVM上唯一不同的就是引用(reference)的空间大小. 这是关于32位系统和64位系统的一个误区. 在Oracle Java6 update23以及之后, 对于heap大小在32GB以下的JVM, 默认会使用32-bit的引用. 所以严格来讲, 只有heap在32GB以上的64-bit的JVM, 才会在引用这个类型上有区别.
关于初级数值类型赋值的原子性
对于所有的JVM, 除了long和double, 其他初级数值类型的赋值都是保证原子性的. 在64-bit JVM中, 因为64-bit的引用类型其赋值一定是原子的, 所以对long和double的赋值也应当是原子的.
多线程下的可见度
但即便是保证原子性, 仍然不能保证多线程环境下各线程对数值变化的"可见度", 因为线程在内存中会生成"影子变量", 对一个变量的赋值并不能保证将其写回主内存, 除非在主内存更新时被自动更新. 如果你希望线程间所读取的数值保持一致, 你必须以某种同步壁垒的形式来访问线程间共享的状态. 例如volatile关键字或锁.
Volatile 关键字
可以参考这篇文章, 介绍得非常详细: http://tutorials.jenkov.com/java-concurrency/volatile.html
volatile关键字用于将变量标识为"存储于主内存". 更精确些, 就是每一次读取变量值的时候, 都必须从计算机的主内存中读取, 而不能从CPU的缓存, 每一次写变量值的时候, 也必须写到主内存, 而不是CPU的缓存.
Volatile附带的"变化可见度"特性
- 如果Thread A 写了一个volatile变量 并且Thread B读取了这个volatile变量, 那么所有在写入这个变量前对A"可见"的变量, 在B读取这个变量之后, "变化"变得对B可见.
- 如果Thread A读取了一个volatile变量, 那么所有在A读取这个变量之前对A"可见"的变量, 在读取后会从主内存中重新读取.
编译时对volatile的处理, 在JDK5以及之后是不同的, 在JDK4时, 对volatile变量的读写与对其他变量的读写指令, 在编译优化阶段可能会被调换顺序, 在JDK5之后保证了发生在volatile变量之前的读写, 不会被调整到volatile变量的读写之后.
JDK5以及之后的顺序保证(Happens-Before Guarantee)
- 如果代码中对某个变量的读取和写入发生在对volatile变量的写入之前, 那么编译后这个读写操作保证不会被调整到对volatile的写入之后. 注意这仅仅是保证发生在volatile写入之前的操作不会放到后面, 但是不能保证volatile写入之后的操作不会被放到前面.
- 如果代码中对某个变量的读取和写入发生在对volatile变量的读取之后, 那么编译后这个读写操作保证不会被调整到对volatile的读取之前. 注意这也不能保证volatile读取之前的操作不会被放到后面.
在有写入的场景下, volatile是不够的
需要用synchronized来保证写入不会互相覆盖, 或者使用AtomLong 或 AtomicReference 这样的原子操作类型数据.
包装类的实例之间比较不能直接用 ==
public static void main(String[] args) {
// TODO Auto-generated method stub
Integer a = new Integer(1);
Integer b = new Integer(1);
int c=1;
Integer e = 1;
System.out.println("a==b:"+(a==b));
System.out.println("a==c:"+(a==c));
System.out.println("a==e:"+(a==e));
System.out.println("c==e:"+(c==e));
}
结果:
a==b:false
a==c:true
a==e:false
c==e:true
Java中初级数值类型的大小, volatile和包装类wrapped type的比较的更多相关文章
- java中Date日期类型的大小比较
方法一:java.util.Date类实现了Comparable接口,可以直接调用Date的compareTo()方法来比较大小 String beginTime = "2018-07-28 ...
- Java中,数值比较大小,以及数值判断相等
Java中,数值比较大小,以及数值判断相等
- Java中的Bigdecimal类型运算
Java中的Bigdecimal类型运算 双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更小的数进行运算和处理.Java在java.math包中提 供的API类BigD ...
- Java中的枚举类型详解
枚举类型介绍 枚举类型(Enumerated Type) 很早就出现在编程语言中,它被用来将一组类似的值包含到一种类型当中.而这种枚举类型的名称则会被定义成独一无二的类型描述符,在这一点上和常量的定义 ...
- java中的null类型---有关null的9件事
摘自 https://blog.csdn.net/qq_25077777/article/details/80174763 今天听到一个问题,java中的null类型,null竟然是一种类型 java ...
- 理解Java中的字符串类型
1.Java内置对字符串的支持: 所谓的内置支持,即不用像C语言通过char指针实现字符串类型,并且Java的字符串编码是符合Unicode编码标准,这也意味着不用像C++那样通过使用string和w ...
- 关于java中的事件类型
java中的Date是为了证明:天才的程序员也会犯错: java中的Calendar是为了证明:普通的程序员也会犯错. ———————————————————— stackoverflow上大部分都推 ...
- Java中的集合类型的继承关系图
Java中的集合类型的继承关系图
- java中,字符串类型的时间数据怎样转换成date类型。
将字符串类型的时间转换成date类型可以使用SimpleDateFormat来转换,具体方法如下:1.定义一个字符串类型的时间:2.创建一个SimpleDateFormat对象并设置格式:3.最后使用 ...
随机推荐
- Eclipse批量替换
情景: 我需要将项目中所有有"上样板"的字样替换为"PCR板",如果寻找单个页面肯定是很麻烦,而且替换很有可能不全,那么该怎么才能完全替换呢? 解决方法: ec ...
- Myeclipse设置快捷键
快捷键中把我们习惯性使用的Alt+/进行代码自动补齐的快捷键改为了ctrl+空格,大家知道这是切换中英文输入法的键,所以需要更改这个快捷键, 1.选择MyEclipse6.0菜单栏中的Window-& ...
- java 数据流的处理
字节流类 功能简单介绍 DataInputStream 包含了读取Java标准数据类型的输入流 DataOutputStream 包含了写Java标准数据类型的输出流 ByteArrayInputSt ...
- OpenShift上部署Redis主从集群
客户有部署有状态服务的需求,单机部署模式相对简单,尝试一下集群部署. 关于Redis的master,slave 以及sentinal的架构和作用不提,有兴趣可以参考之前的博客 https://www. ...
- 新买的mac笔记本,发现vi编辑器没有颜色的解决方案
新买的mac笔记本,发现vi编辑器没有颜色的解决方案 我在网络上找了一些资料,发现都有些问题,尤其是一些让修改根目录上的文件,发现根本无法修改. 但是在网络上找到了这篇文章: http://super ...
- 同时启动多个Tomcat服务器
以下步骤能够同时启动两个tomcat:1.特别要注意:不要设置CATALINA_HOME 2.分别修改安装目录下的conf子目录中的server.xml文件: a.修改http访问端口(默认为8080 ...
- (笔试题)小米Git
题目: git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常常需 ...
- mysql存储引擎简析
一.常见存储引擎特性 Innodb 具有提交.回滚和崩溃恢复能力的事务安全.支持外键.使用mvcc以及行锁来提供事务支持,因此支持高并发.适用于写频繁,并发率高的应用. Myisam 不支持事务和灾难 ...
- cocos lua 加密与解密 混淆 (版本号cocos3.4)
cocos luacompile cocos luacompile Overview Usage Available Arguments Samples Overview Compile the .l ...
- Octave中plot函数的用法
octave:14> help plot'plot' is a function from the file C:\Octave\Octave3.6.4_gcc4.6.2\share\octav ...