Refactor variable ConcurrentInitializer implementations to remove

duplication of initialize() method
This commit is contained in:
Gary Gregory 2023-10-12 14:04:34 -04:00
parent c1bd1e50a9
commit 11d2deca1f
5 changed files with 45 additions and 56 deletions

View File

@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.lang3.concurrent;
/**
* Abstracts and defines operations for ConcurrentInitializer implementations.
*
* @param <T> the type of the object managed by this initializer class.
* @param <E> The exception type thrown by {@link #initialize()}.
* @since 3.14.0
*/
public abstract class AbstractConcurrentInitializer<T, E extends Exception> implements ConcurrentInitializer<T> {
/**
* Creates and initializes the object managed by this {@code
* ConcurrentInitializer}. This method is called by {@link #get()} when the object is accessed for the first time. An implementation can focus on the
* creation of the object. No synchronization is needed, as this is already handled by {@code get()}.
*
* @return the managed data object
* @throws E if an error occurs during object creation
*/
protected abstract T initialize() throws E;
}

View File

@ -62,7 +62,7 @@ import java.util.concurrent.atomic.AtomicReference;
* @since 3.0
* @param <T> the type of the object managed by this initializer class
*/
public abstract class AtomicInitializer<T> implements ConcurrentInitializer<T> {
public abstract class AtomicInitializer<T> extends AbstractConcurrentInitializer<T, RuntimeException> {
/** Holds the reference to the managed object. */
private final AtomicReference<T> reference = new AtomicReference<>();
@ -89,17 +89,4 @@ public abstract class AtomicInitializer<T> implements ConcurrentInitializer<T> {
return result;
}
/**
* Creates and initializes the object managed by this {@code
* AtomicInitializer}. This method is called by {@link #get()} when the
* managed object is not available yet. An implementation can focus on the
* creation of the object. No synchronization is needed, as this is already
* handled by {@code get()}. As stated by the class comment, it is possible
* that this method is called multiple times.
*
* @return the managed data object
* @throws ConcurrentException if an error occurs during object creation
*/
protected abstract T initialize() throws ConcurrentException;
}

View File

@ -51,8 +51,8 @@ import java.util.concurrent.atomic.AtomicReference;
* @since 3.0
* @param <T> the type of the object managed by this initializer class
*/
public abstract class AtomicSafeInitializer<T> implements
ConcurrentInitializer<T> {
public abstract class AtomicSafeInitializer<T> extends AbstractConcurrentInitializer<T, RuntimeException> {
/** A guard which ensures that initialize() is called only once. */
private final AtomicReference<AtomicSafeInitializer<T>> factory =
new AtomicReference<>();
@ -79,17 +79,4 @@ public abstract class AtomicSafeInitializer<T> implements
return result;
}
/**
* Creates and initializes the object managed by this
* {@link AtomicInitializer}. This method is called by {@link #get()} when
* the managed object is not available yet. An implementation can focus on
* the creation of the object. No synchronization is needed, as this is
* already handled by {@code get()}. This method is guaranteed to be called
* only once.
*
* @return the managed data object
* @throws ConcurrentException if an error occurs during object creation
*/
protected abstract T initialize() throws ConcurrentException;
}

View File

@ -81,8 +81,8 @@ import java.util.concurrent.Future;
* @since 3.0
* @param <T> the type of the object managed by this initializer class
*/
public abstract class BackgroundInitializer<T> implements
ConcurrentInitializer<T> {
public abstract class BackgroundInitializer<T> extends AbstractConcurrentInitializer<T, Exception> {
/** The external executor service for executing tasks. */
private ExecutorService externalExecutor; // @GuardedBy("this")
@ -262,18 +262,6 @@ public abstract class BackgroundInitializer<T> implements
return 1;
}
/**
* Performs the initialization. This method is called in a background task
* when this {@link BackgroundInitializer} is started. It must be
* implemented by a concrete subclass. An implementation is free to perform
* arbitrary initialization. The object returned by this method can be
* queried using the {@link #get()} method.
*
* @return a result object
* @throws Exception if an error occurs
*/
protected abstract T initialize() throws Exception;
/**
* Creates a task for the background initialization. The {@link Callable}
* object returned by this method is passed to the {@link ExecutorService}.

View File

@ -76,7 +76,7 @@ package org.apache.commons.lang3.concurrent;
* @since 3.0
* @param <T> the type of the object managed by this initializer class
*/
public abstract class LazyInitializer<T> implements ConcurrentInitializer<T> {
public abstract class LazyInitializer<T> extends AbstractConcurrentInitializer<T, ConcurrentException> {
private static final Object NO_INIT = new Object();
@ -110,18 +110,6 @@ public abstract class LazyInitializer<T> implements ConcurrentInitializer<T> {
return result;
}
/**
* Creates and initializes the object managed by this {@code
* LazyInitializer}. This method is called by {@link #get()} when the object
* is accessed for the first time. An implementation can focus on the
* creation of the object. No synchronization is needed, as this is already
* handled by {@code get()}.
*
* @return the managed data object
* @throws ConcurrentException if an error occurs during object creation
*/
protected abstract T initialize() throws ConcurrentException;
/**
* Tests whether this instance is initialized. Once initialized, always returns true.
*