Является ли эта версия Java с двойной проверкой блокировки безопасной? - PullRequest
1 голос
/ 04 июля 2019

Я пытаюсь реализовать многоразовую функционально-подобную версию шаблона двойной проверки блокировки (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());
}

Все тесты и анализ, которые я провел, не выявили проблем (например, дублированные экземпляры).Но многопоточный и параллельный тест для меня не такая простая задача.Так вы, ребята, могли бы помочь мне с этим?Могу ли я сказать, что эта реализация является поточно-ориентированной и дает ожидаемые результаты?

...