这是我的单例模式自定义类。在这段代码中,我使用了双重检查锁定,如下所示。当我在某些来源上阅读了许多帖子时,他们说双重检查很有用,因为它可以防止同时运行的两个并发线程生成两个不同的对象。
public class DoubleCheckLocking {
public static class SearchBox {
private static volatile SearchBox searchBox;
// private constructor
private SearchBox() {}
// static method to get instance
public static SearchBox getInstance() {
if (searchBox == null) { // first time lock
synchronized (SearchBox.class) {
if (searchBox == null) { // second time lock
searchBox = new SearchBox();
}
}
}
return searchBox;
}
}
我还是不太明白上面的代码。实例为空时,如果两个线程一起运行同一行代码,有什么问题?
if (searchBox == null) {
synchronized (SearchBox.class) {
if (searchBox == null) {
searchBox = new SearchBox();
}
}
}
当它出现时。两个线程都会看到对象为空。然后两者同步。然后,他们再次检查,仍然看到它为空。并创建两个不同的对象。哎呀。
请为我解释一下。我理解错了什么?
谢谢:)
最佳答案
不,由于您正在获取 SearchBox.class
的锁定,因此一次只有一个线程会进入同步块(synchronized block)。所以第一个线程进入然后发现 searchBox
为空并创建它然后离开同步块(synchronized block),然后第二个线程进入 block 然后它发现 searchBox
不为空因为第一个线程已经创建了它,所以它不会创建 searchBox
的新实例。
双重检查模式用于避免每次执行代码时都获得锁。如果调用没有一起发生,那么第一个条件将失败,代码执行将不会执行锁定,从而节省资源。
关于java - 单例中的双重检查锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18093735/