再说J.U.C之并发基础工具

本文深入探讨Java并发编程中的三个关键组件:Unsafe、synchronized和LockSupport。 Unsafe提供了低级别的内存操作,包括对象属性偏移量获取、修改对象属性和CAS操作,其CAS操作通过总线锁定和缓存行锁定确保原子性。synchronized的同步原理涉及对象头、偏向锁和轻量级锁,降低了锁的开销。LockSupport作为线程控制的基础工具,提供park()和unpark()方法,与wait/notify相比,具有更好的可控性和效率。
摘要由CSDN通过智能技术生成

上一讲我们讲述了线程池整个的过程,这一讲我们来先底层的3个组件,synchronized,Unsafe以及LockSupport

Unsafe

常用api

/**
     * 获取对象指定Field对应的内存地址偏移量,可以理解为跟C++中的指针一样,获取到了属性的地址,在一个对象中
     * 属性的偏移地址是固定的,不会发生变化
     * @param var1
     * @return
     */
    public native long objectFieldOffset(Field var1);

    /**
     * 可以修改对象属性值
     * @param var1 对象实例
     * @param var2 属性偏移量
     * @param var4 要修改的值
     */
    public native void putInt(Object var1, long var2, int var4);

    /**
     * 获取对象实例
     * @param var1
     * @return
     * @throws InstantiationException
     */
    public native Object allocateInstance(Class<?> var1) throws InstantiationException;

    /**
     * CAS
     * @param var1
     * @param var2
     * @param var4
     * @param var5
     * @return
     */
    public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

Unsafe实例的获取

首先从名字就可以看出来这个类是不安全的,比较敏感,所以jdk底层也没有开放使用这个类,该类提供了单利模式获取Unsafe对象的方法:

 public static Unsafe getUnsafe() {
        Class var0 = Reflection.getCallerClass();
        //类加载器必须是root类加载器,否则不允许使用该类
        if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
            throw new SecurityException("Unsafe");
        } else {
            return theUnsafe;
        }
    }

所以我们在应用中要获取该类的实例,就得通过反射获取了,反射获取静态私有属性的方式:

Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);

api实例使用

对象属性偏移量获取
public class UnsafeTest {
    private  Integer abc = 10;
    public UnsafeTest(){
        abc = 10;
    }

    public  Integer getAbc() {
        return abc;
    }

    public static void main(String[] args) {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            Unsafe unsafe = (Unsafe)theUnsafe.get(null);

            Class<UnsafeTest> unsafeTestClass = UnsafeTest.class;
            Field[] declaredFields = unsafeTestClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println(declaredField.getName() + ",偏移地址:" + unsafe.objectFieldOffset(declaredField));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

对象的属性偏移量地址经过编译后,一般不会再发生变化

修改对象属性值
  @Test
    public void updateObjectField()throws Exception{
        Unsafe unsafe = getUnsafe();
        UnsafeTest unsafeTest = new UnsafeTest();
        Field abc = unsafeTest.getClass().getDeclaredField("abc");
        System.out.println(unsafeTest.getAbc());
        unsafe.putObject(unsafeTest, unsafe.objectFieldOffset(abc), 40);
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值