双检锁

public static Object getBean(String beanName) {
    // 双检锁保证beanMap中确实没有beanName对应的对象
    if (!beanMap.containsKey(beanName)) {
        synchronized (BeanFactory.class) {
            if (!beanMap.containsKey(beanName)) {
                // 过了双检锁,证明确实没有,可以执行反射创建
                try {
                    Class<?> beanClazz = Class.forName(properties.getProperty(beanName));
                    Object bean = beanClazz.newInstance();
                    // 反射创建后放入缓存再返回
                    beanMap.put(beanName, bean);
                } catch (ClassNotFoundException e) {
                    throw new RuntimeException("BeanFactory have not [" + beanName + "] bean!", e);
                } catch (IllegalAccessException | InstantiationException e) {
                    throw new RuntimeException("[" + beanName + "] instantiation error!", e);
                }
            }
        }
    }
    return beanMap.get(beanName);
}

解释:第一个if判断避免其他无用线程竞争锁造成线程浪费,第二个if判断可以拦截除第一个获得对象锁线程外的线程

如果没有第二个if,如果线程A,线程B都阻塞到了获取线程锁的位置,A获得了锁----实例化对象----put到map---释放锁----B获得锁----实例化对象---put到map---释放锁,还是相当于实例化两次对象

posted @ 2022-07-02 09:02  KeepSmiling_me  阅读(108)  评论(0)    收藏  举报