How to implement thread-safe lazy initialization?

后端 未结 12 826
一整个雨季
一整个雨季 2020-11-28 04:13

What are some recommended approaches to achieving thread-safe lazy initialization? For instance,

// Not thread-safe
public Foo getI         


        
12条回答
  •  醉话见心
    2020-11-28 04:59

    Thinking about lazy initialization, I would expect getting a "almost real" object that just decorates the still not initialized object.

    When the first method is being invoked, the instance within the decorated interface will be initialized.

    * Because of the Proxy usage, the initiated object must implement the passed interface.

    * The difference from other solutions is the encapsulation of the initiation from the usage. You start working directly with DataSource as if it was initialized. It will be initialized on the first method's invocation.

    Usage:

    DataSource ds = LazyLoadDecorator.create(dsSupplier, DataSource.class)
    

    Behind the scenes:

    public class LazyLoadDecorator implements InvocationHandler {
    
        private final Object syncLock = new Object();
        protected volatile T inner;
        private Supplier supplier;
    
        private LazyLoadDecorator(Supplier supplier) {
            this.supplier = supplier;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (inner == null) {
                synchronized (syncLock) {
                    if (inner == null) {
                        inner = load();
                    }
                }
            }
            return method.invoke(inner, args);
        }
    
        protected T load() {
            return supplier.get();
        }
    
        @SuppressWarnings("unchecked")
        public static  T create(Supplier factory, Class clazz) {
            return (T) Proxy.newProxyInstance(LazyLoadDecorator.class.getClassLoader(),
                    new Class[] {clazz},
                    new LazyLoadDecorator<>(factory));
        }
    }
    

提交回复
热议问题