欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unsafe的用法

程序员文章站 2023-12-28 18:01:34
...
我们写程序,一般不直接使用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);







上一篇:

下一篇: