Copyright (c) 2014, 2016 IBM Corporation and others.
This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
IBM Corporation - initial API and implementation
/*******************************************************************************
* Copyright (c) 2014, 2016 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.internal.container;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
A helper class for doing lazy initialization
Type parameters: - <V> – the type of object to lazy initialize
/**
* A helper class for doing lazy initialization
*
* @param <V> the type of object to lazy initialize
*/
public class AtomicLazyInitializer<V> {
private final AtomicReference<V> holder = new AtomicReference<>();
Gets the current value. If the value has not been initialized then null
is returned; Returns: the current value
/**
* Gets the current value. If the value has not been initialized then
* {@code null} is returned;
* @return the current value
*/
public final V get() {
return holder.get();
}
Atomically gets the current initialized value. If the current value is null
then the supplied initializer is called to create the value returned. Params: - initializer – the initializer to call if the current value is
null
Returns: the initialized value. May return null
if initializer returns null.
/**
* Atomically gets the current initialized value. If the current value is {@code null}
* then the supplied initializer is called to create the value returned.
* @param initializer the initializer to call if the current value is {@code null}
* @return the initialized value. May return {@code null} if initializer returns null.
*/
public final V getInitialized(Callable<V> initializer) {
V result = holder.get();
if (result != null) {
return result;
}
// Must hold a lock to ensure the operation is atomic.
synchronized (holder) {
result = holder.get();
if (result != null) {
return result;
}
try {
result = initializer.call();
} catch (Exception e) {
unchecked(e);
}
holder.set(result);
return result;
}
}
Gets the current value and clears the value for future calls to this lazy initializer.
Returns: the current value
/**
* Gets the current value and clears the value for future calls to this lazy initializer.
* @return the current value
*/
public final V getAndClear() {
return holder.getAndSet(null);
}
private static <T> T unchecked(Exception exception) {
return AtomicLazyInitializer.<T, RuntimeException> unchecked0(exception);
}
@SuppressWarnings("unchecked")
private static <T, E extends Exception> T unchecked0(Exception exception) throws E {
throw (E) exception;
}
}