原子性指的是一个操作不可以中断。
举个例子说明:
/**
* @program:tpb
* @description:多线程下Long的原子性
**/
public class MultiThreadLong {
public static long t = 0;
public static class writer implements Runnable {
private long to;
public writer(long to) {
this.to = to;
}
@Override
public void run() {
while (true) {
MultiThreadLong.t = to;
Thread.yield();
}
}
}
public static class ReadT implements Runnable {
@Override
public void run() {
while (true) {
long tmp = MultiThreadLong.t;
if (tmp != 111L && tmp != -999L) {
System.out.println(tmp);
Thread.yield();
}
}
}
}
public static void main(String[] args) {
new Thread( new writer(111L)).start();
new Thread(new writer(-999L)).start();
new Thread(new ReadT()).start();
}
}
运行结果:
4294966297
-4294967185
-4294967185
为什么这么输出:
这是因为 jvm是32bit 而 long 的长度是64位 无法保证原子性。 如果是jvm 64bit 不会出现此问题。(Terminal下运行 java -d32 -version 或 java -d64 -version 命令)
jdk中定义long占8个字节 ===> 64位
long的取值范围是-2^63 - 2^63-1 ,也就是-9223372036854775808 -9223372036854775807
jvm 32bit和 jvm 64bit 区别:
理论上来说32位的JVM有4G的堆大小限制。但是因为各种条件限制比如交换区,内核地址空间使用,内存碎片,虚拟管理机的管理开销,实际上可用的堆的大小远远比理论上的4G要少
32位windows的机器上,堆最大可以达到1.4G至1.6G。
32位linux的机器上,堆最大可以达到2G
而在64位的操作系统上,JVM32bit,堆大小可以达到4G 。
CPU对32和64位处理运算介绍
jdk-8u251-macosx-x64.dmg 表示64位操作系统可以安装
x64 和 i586 或x86 指的是CUP架构指令集,X86支持32位运算(cpu可以一次性处理4个字节),X64支持64位运算(cpu可以一次性处理8个字节)。
对内存有什么影响(内存调优需要知道)?
1、32位和64位一般是指CPU的通用寄存器位宽,所以64位的CPU位宽增加一倍。
2、可寻址范围大大扩展,32位系统支持最大内存位4G,64位系统理论支持最大内存2^64=18446,744,073,709,551,616,约1600万TB,相当于16EB。
Java代码首先被编译成字节码文件,再由JVM将字节码文件翻译成机器语言。
总结:由于jvm32bit 和 jvm64bit 将字节码翻译成机器码 不同导致 上述例子在 jvm32bit和jvm64bit执行结果不同。