    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.lang3.concurrent;
    018
    019    /**
    020     * <p>
    021     * This class provides a generic implementation of the lazy initialization
    022     * pattern.
    023     * </p>
    024     * <p>
    025     * Sometimes an application has to deal with an object only under certain
    026     * circumstances, e.g. when the user selects a specific menu item or if a
    027     * special event is received. If the creation of the object is costly or the
    028     * consumption of memory or other system resources is significant, it may make
    029     * sense to defer the creation of this object until it is really needed. This is
    030     * a use case for the lazy initialization pattern.
    031     * </p>
    032     * <p>
    033     * This abstract base class provides an implementation of the double-check idiom
    034     * for an instance field as discussed in Joshua Bloch's "Effective Java", 2nd
    035     * edition, item 71. The class already implements all necessary synchronization.
    036     * A concrete subclass has to implement the {@code initialize()} method, which
    037     * actually creates the wrapped data object.
    038     * </p>
    039     * <p>
    040     * As an usage example consider that we have a class {@code ComplexObject} whose
    041     * instantiation is a complex operation. In order to apply lazy initialization
    042     * to this class, a subclass of {@code LazyInitializer} has to be created:
    043     *
    044     * <pre>
    045     * public class ComplexObjectInitializer extends LazyInitializer&lt;ComplexObject&gt; {
    046     *     &#064;Override
    047     *     protected ComplexObject initialize() {
    048     *         return new ComplexObject();
    049     *     }
    050     * }
    051     * </pre>
    052     *
    053     * Access to the data object is provided through the {@code get()} method. So,
    054     * code that wants to obtain the {@code ComplexObject} instance would simply
    055     * look like this:
    056     *
    057     * <pre>
    058     * // Create an instance of the lazy initializer
    059     * ComplexObjectInitializer initializer = new ComplexObjectInitializer();
    060     * ...
    061     * // When the object is actually needed:
    062     * ComplexObject cobj = initializer.get();
    063     * </pre>
    064     *
    065     * </p>
    066     * <p>
    067     * If multiple threads call the {@code get()} method when the object has not yet
    068     * been created, they are blocked until initialization completes. The algorithm
    069     * guarantees that only a single instance of the wrapped object class is
    070     * created, which is passed to all callers. Once initialized, calls to the
    071     * {@code get()} method are pretty fast because no synchronization is needed
    072     * (only an access to a <b>volatile</b> member field).
    073     * </p>
    074     *
    075     * @author Apache Software Foundation
    076     * @version $Id: LazyInitializer.java 929189 2010-03-30 16:49:22Z oheger $
    077     * @param <T> the type of the object managed by this initializer class
    078     */
    079    public abstract class LazyInitializer<T> implements ConcurrentInitializer<T> {
    080        /** Stores the managed object. */
    081        private volatile T object;
    082
    083        /**
    084         * Returns the object wrapped by this instance. On first access the object
    085         * is created. After that it is cached and can be accessed pretty fast.
    086         *
    087         * @return the object initialized by this {@code LazyInitializer}
    088         * @throws ConcurrentException if an error occurred during initialization of
    089         * the object
    090         */
    091        public T get() throws ConcurrentException {
    092            // use a temporary variable to reduce the number of reads of the
    093            // volatile field
    094            T result = object;
    095
    096            if (result == null) {
    097                synchronized (this) {
    098                    result = object;
    099                    if (result == null) {
    100                        object = result = initialize();
    101                    }
    102                }
    103            }
    104
    105            return result;
    106        }
    107
    108        /**
    109         * Creates and initializes the object managed by this {@code
    110         * LazyInitializer}. This method is called by {@link #get()} when the object
    111         * is accessed for the first time. An implementation can focus on the
    112         * creation of the object. No synchronization is needed, as this is already
    113         * handled by {@code get()}.
    114         *
    115         * @return the managed data object
    116         * @throws ConcurrentException if an error occurs during object creation
    117         */
    118        protected abstract T initialize() throws ConcurrentException;
    119    }