一度に 1 つずつロックを取得せずに、他の 9 つのスレッドすべてを実行したいと言っているのですか。
最初に、初期化を待った後にロックを取得することによるパフォーマンスの問題はごくわずかであることに言及しなければなりません。第二に、シングルトンは悪であり、それらを実装するためのより良い方法があります。
ただし、ロックを部分的に再実装したい場合は、これを行うことができます。これを行うための既製のものがあるかもしれませんがFuture
、何も見えません。とにかく、私の頭の上からの悪い実装:
private static final AtomicReference<Object> ref = new AtomicReference<>();
// <Object> as we require two distinguished values. :(
// (I guess could use a mark.)
public static Singleton getInstance() {
for (;;) { // May want to play with park to avoid spinning.
Object obj = ref.get();
if (obj instanceof Singleton) {
return (Singleton)obj;
}
if (ref.weakCompareAndSet(null, Thread.currentThread())) {
Singleton instance = null; // To reset on fail.
try {
instance = new Singleton();
} finally {
ref.set(instance);
}
return instance;
}
}
}
例外がないと仮定すると、複雑になりすぎずに少し改善できると思います。
{
Object obj = ref.get();
if (obj instanceof Singleton) {
return (Singleton)obj;
}
}
if (ref.compareAndSet(null, Thread.currentThread())) {
Singleton instance = new Singleton();
ref.set(instance);
return instance;
}
for (;;) {
Object obj = ref.get();
if (obj instanceof Singleton) {
return (Singleton)obj;
}
}