我正在尝试在Java中实现可重用的类似功能的双重检查锁(DCL)模式。
实际上,Java中的DCL模式存在许多已知问题,例如ones。因此,我正在尝试检查开发的解决方案是否存在任何缺陷。
这是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());
}
我所做的所有测试和分析均未显示任何问题(例如,重复的实例)。但是对我来说,多线程和并发测试并不是一件容易的事。你们能帮我这个忙吗?我可以说这种实现是线程安全的,并且可以产生预期的结果吗?