Я пытаюсь реализовать многоразовую функционально-подобную версию шаблона двойной проверки блокировки (DCL) в Java.
Действительно, существует много известных проблем с шаблоном DCL в Java, таких как единицы .Поэтому я пытаюсь проверить, есть ли в разработанном мною решении недостатки.
Вот код исполнителя DCL:
public class DoubleCheckedLockExecutor {
public <T> T getOrCreate(Supplier<T> supplier, Supplier<T> builder, Consumer<T> consumer, Predicate<T> build) {
if (build.test(supplier.get())) {
synchronized (this) {
if (build.test(supplier.get())) {
consumer.accept(builder.get());
}
}
}
return supplier.get();
}
}
А вот класс Singleton, который его использует:
public class Singleton {
private static Singleton instance = null;
private static final AtomicInteger instanceCount = new AtomicInteger();
private static final DoubleCheckedLockExecutor dclExec = new DoubleCheckedLockExecutor();
private Singleton() {
instanceCount.incrementAndGet();
}
public static Singleton getInstance() {
return dclExec.getOrCreate(() -> instance, Singleton::new, s -> instance = s, s -> s == null);
}
public static int getInstanceCount() {
return instanceCount.get();
}
}
И, наконец, некоторый тестовый код:
@Test
public final void testGetOrCreate() {
int calls = 1000;
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
try {
for (int i = 0; i < calls; i++) {
executor.execute(() -> Singleton.getInstance());
}
} catch (Exception e) {
e.printStackTrace();
}
executor.shutdown();
while (!executor.isTerminated()) {
}
assertEquals(1, Singleton.getInstanceCount());
}
Все тесты и анализ, которые я провел, не выявили проблем (например, дублированные экземпляры).Но многопоточный и параллельный тест для меня не такая простая задача.Так вы, ребята, могли бы помочь мне с этим?Могу ли я сказать, что эта реализация является поточно-ориентированной и дает ожидаемые результаты?