SingletonHolder reinvented.
Don't blame me I reinvent a wheel again...
I understend this subject was discussed many times.
but I would like to know what do you think about my implementation.
package ru.m12h.utils;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Callable;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicReference;
public class SingletonHolder<T> implements Callable<T> {
private AtomicReference<T> _instance = new AtomicReference<T>();
private AtomicReference<FutureTask<T>> _future = new
AtomicReference<FutureTask<T>>();
private Callable<T> _callable;
public SingletonHolder() {
}
public SingletonHolder(Callable<T> _callable) {
this._callable = _callable;
}
public T get() {
try {
T result = _instance.get();
if (result != null) {
return result;
}
if (_future.compareAndSet(null, new FutureTask<T>(_callable !=
null ? _callable : this))) {
_future.get().run();
}
result = _future.get().get();
if (result == null) {
throw new IllegalStateException();
}
_instance.compareAndSet(null, result);
return result;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Thread interrupted during lazy
initialization.", e);
} catch (ExecutionException e) {
throw new RuntimeException("Exception during lazy initialization.",
e.getCause());
}
}
public T call() throws Exception {
throw new IllegalStateException("The call() method is not
implemented");
}
//
// Test SingletonHolder ...
//
public static SingletonHolder<String> holder = new
SingletonHolder<String>() {
public String call() throws Exception {
return "Singleton value is created from thread: " +
Thread.currentThread().getName();
}
};
public static void main(String[] args) {
int count = 10;
final CyclicBarrier barrier = new CyclicBarrier(count);
for (int i = 0; i < count; i++ ) {
new Thread() {
public void run() {
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.printf("Thread %s, time: %d, got value [%s]%n",
Thread.currentThread().getName(),
System.currentTimeMillis(),
holder.get());
}
}.start();
}
}
}
The major advantage of this implementation against the following:
public class Singleton {
static class SingletonHolder {
static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
is that I can resent and re-initialize value of singleton I case, for
example, of redeploy or smth.
It's important for me to be able to resent and re-initialize singleton
object.