设为首页 加入收藏

TOP

Java不能操作内存?Unsafe了解一下(五)
2023-08-26 21:11:18 】 浏览:122
Tags:Java 能操作 Unsafe 解一下
Volatile(Object var1, long var2); //将var4值放入指定var1对象的var2偏移量位置,直接刷新到主内存 public native void putLongVolatile(Object var1, long var2, long var4); // 比较并替换原值为新值,操作成功返回true否则false,var1是指定对象,var2是偏移量地址,var4是预期的原值,var5是要更新的新值 public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6); // 自旋获取原值并增加数值,var1是指定对象,var2是偏移量地址,var4是要增加的值 public final int getAndAddLong(Object var1, long var2, long var4) { int var5; do { var5 = this.getLongVolatile(var1, var2); } while(!this.compareAndSwapLong(var1, var2, var5, var5 + var4)); return var5; } // 自旋获取原值并设置新值,var1是指定对象,var2是偏移量地址,var4是要设置的新值 public final int getAndSetLong(Object var1, long var2, long var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapLong(var1, var2, var5, var4)); return var5; } // 还有Object相关的cas操作这里没有列出

举几个栗子

public void test3() throws Exception {
    Cat cat = new Cat("Kitty", 1000);
    long speedOffset = unsafe.objectFieldOffset(Cat.class.getDeclaredField("speed"));
    System.out.println("before putLongVolatile,getLongVolatile=" + unsafe.getLongVolatile(cat, speedOffset));
    // 设置speed的值为2000
    unsafe.putLongVolatile(cat, speedOffset, 2000);
    System.out.println("after putLongVolatile,getLongVolatile=" + unsafe.getLongVolatile(cat, speedOffset));
    // 到这里speed的值是2000,但是compareAndSwapLong里预期的值是3000,所以cas失败,返回false
    System.out.println("compareAndSwapLong result:" + unsafe.compareAndSwapLong(cat, speedOffset, 3000, 4000));
    // 到这里speed的值是2000,但是compareAndSwapLong里预期的值是2000,cas更新成功,返回true
    System.out.println("compareAndSwapLong result:" + unsafe.compareAndSwapLong(cat, speedOffset, 2000, 4000));
    // cas后speed的值就是4000了
    System.out.println("after compareAndSwapLong,getLongVolatile=" + unsafe.getLongVolatile(cat, speedOffset));
    // getAndAddLong会返回原值4000,新值=原值+10
    System.out.println("getAndAddLong:" + unsafe.getAndAddLong(cat, speedOffset, 10));
    // getAndAddLong后speed新值是4010
    System.out.println("after getAndAddLong,getLongVolatile=" + unsafe.getLongVolatile(cat, speedOffset));
    // getAndSetLong会返回原值4010,新值=要设置的新值1000
    System.out.println("getAndSetLong:" + unsafe.getAndSetLong(cat, speedOffset, 1000));
    // getAndSetLong后speed新值是1000
    System.out.println("after getAndSetLong,getLongVolatile=" + unsafe.getLongVolatile(cat, speedOffset));
}

输出结果:

static...
before putLongVolatile,getLongVolatile=1000
after putLongVolatile,getLongVolatile=2000
compareAndSwapLong result:false
compareAndSwapLong result:true
after compareAndSwapLong,getLongVolatile=4000
getAndAddLong:4000
after getAndAddLong,getLongVolatile=4010
getAndSetLong:4010
after getAndSetLong,getLongVolatile=1000

线程调度及同步

// 释放线程让其继续执行,多次调用只会生效一次,可以在park前调用
public native void unpark(Object thread);
// 阻塞线程,isAbsolute为true:表示绝对时间,time的单位是毫秒ms,false:表示相对时间,time的单位是纳秒级的时间
public native void park(boolean isAbsolute, long time);
//以下3个方法均标注过期了,建议使用其他同步方法
// 获取var1的对象锁,没获取到则阻塞等待
public native void monitorEnter(Object var1);
// 尝试获取var1的对象锁,不阻塞,获取到则返回true,没获取到返回false
public native boolean tryMonitorEnter(Object var1);
// 释放var1对象锁
public native void monitorExit(Obje
首页 上一页 2 3 4 5 6 7 下一页 尾页 5/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇10、Spring之AOP概述 下一篇new ArrayList 不当导致 CPU 飙升..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目