Synchronization 单例模式-为什么我们需要两次检查可变变量的初始化?

Synchronization 单例模式-为什么我们需要两次检查可变变量的初始化?,synchronization,thread-safety,critical-section,Synchronization,Thread Safety,Critical Section,只有当条件uniqueInstance==null设置为true时,线程才会输入同步代码,那么在临界区内需要再次检查它吗 因为在检查和同步调用之间,您可能被另一个进程中断,该进程获取信号量、写入单例并退出。除非再次检查,否则可能会覆盖其他进程已初始化的值 另一方面,如果使整个方法同步化,则每次调用单例时都要支付同步成本,而不仅仅是第一次调用。最好检查两次。啊,现在我明白了-你的意思是说互斥仅对“线程”有效,但其他一些“进程”可能会破坏这两者之间的事情?在这种情况下,我们不能使用信号量和互斥-两者

只有当条件
uniqueInstance==null
设置为true时,线程才会输入同步代码,那么在临界区内需要再次检查它吗


因为在检查和同步调用之间,您可能被另一个进程中断,该进程获取信号量、写入单例并退出。除非再次检查,否则可能会覆盖其他进程已初始化的值


另一方面,如果使整个方法同步化,则每次调用单例时都要支付同步成本,而不仅仅是第一次调用。最好检查两次。

啊,现在我明白了-你的意思是说互斥仅对“线程”有效,但其他一些“进程”可能会破坏这两者之间的事情?在这种情况下,我们不能使用信号量和互斥-两者都有吗?具有更高优先级的线程可以随时唤醒。这和过程没有区别。这两种方法都可以先中断您并设置单例。但是,具有较高优先级的线程不会进入互斥锁部分来设置变量?如果您有互斥锁,则不会。但是获取互斥锁是有代价的,而双重检查锁定的目的是避免在99.9%的情况下获取锁(无论是互斥锁、信号量还是同步锁)的代价,在这种情况下,您不需要它(读取单例),而在这样做的情况下(当单例未初始化时)将其保持在0.1%。这需要一个便宜的测试、一个锁和另一个测试,以确保在锁定之前没有被中断。