测试jvm对double、long是否原子性操作

public  class Test implements Runnable{
    private static long field = 0;
    private volatile long value;

    public long getValue() {
        return value;
    }
    public void setValue(long value) {
        this.value = value;
    }
    public Test(long value) {
        this.setValue(value);
    }
    @Override
    public void run() {
        int i = 0;
        while(true){
        while (i < 10000000) {
            Test.field = this.getValue();

            long temp = Test.field;
            if (temp != 1L && temp != -1L) {
                System.out.println("出现错误结果" + temp);
                System.exit(0);
            }
            i++;
        }
        System.out.println("运行正确");
    }}

    public static void main(String[] args) throws InterruptedException {
        // 获取并打印当前JVM是32位还是64位的
        String arch = System.getProperty("sun.arch.data.model");
        System.out.println(arch+"-bit");
        Test t1 = new Test(1);
        Test t2 = new Test(-1);
        Thread T1 = new Thread(t1);
        Thread T2 = new Thread(t2);
        T1.start();
        T2.start();
        T1.join();
        T2.join();
    }}

解释:

如果jvm是64位的,那么field只能是1或-1.

如果jvm是32位的,那么

对于long和double变量,把他们作为2个原子性的32位值来对待,而不是一个原子性的64位值,
这样将一个long型的值保存到内存的时候,可能是2次32位的写操作,
2个竞争线程想写不同的值到内存的时候,可能导致内存中的值是不正确的结果。

1、写入高位32位值(线程2)
2、写入高位32位值(线程1)
3、写入低位32位值(线程1)
4、写入低位32位值(线程2)

即结果可能出现

32-bit出现错误结果-4294967295运行正确

即有线程t2先进行了写入高32位值,然后被中断,t1又进行写入高位和低位32位值,被中断,然后t1又写入低32位值,导致t2中的field值前32位是0,后32位是1所以结果是4294967295为什么是负呢,暂时不清楚

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值