Unsafe的用法

1 篇文章 0 订阅
1 篇文章 0 订阅
我们写程序,一般不直接使用Unsafe类。 JDK的类特别是并发框架中大量使用到Unsafe的功能,比如:AtomicInteger, LockSupport.所以,了解Unsafe提供的功能与机制是非常必要的。

如何获取Unsafe对象?

Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);



功能1:操作对象的属性, 可以绕过private关键字。


TestUnsafe a = (TestUnsafe) unsafe.allocateInstance(aClass);
Field f = TestUnsafe.class.getDeclaredField("num");
long offset = unsafe.objectFieldOffset(f);
unsafe.compareAndSwapInt(a, offset, 0, 2);
System.out.println(a);


功能2:直接操作DirectBuffer,高效。


File counters = new File(System.getProperty("java.io.tmpdir"), "counters.deleteme");
System.out.println(counters.getAbsolutePath());
counters.deleteOnExit();
FileChannel fc = new RandomAccessFile(counters, "rw").getChannel();
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
long address = ((DirectBuffer) mbb).address();
int value = unsafe.getIntVolatile(null, address);
System.out.println("---" + value);
System.out.println(unsafe.compareAndSwapInt(null, address, value, 2));



功能3:线程的阻塞与唤醒:

Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程t阻塞");
unsafe.park(false, 0l);
System.out.println("线程t唤醒");
}
});
t.start();

Thread.sleep(10000);
//线程挂起和恢复
// unsafe.park(false,1000*1000*1000*100); //nanosecond
System.out.println("唤醒t!");
unsafe.unpark(t);



功能4:CAS操作:

TestUnsafe a = (TestUnsafe) unsafe.allocateInstance(aClass);
Field f = TestUnsafe.class.getDeclaredField("num");
long offset = unsafe.objectFieldOffset(f);
unsafe.compareAndSwapInt(a, offset, 0, 2);
System.out.println(a);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值