Схема блокировки с двойной проверкой примерно равна:
у вас есть операция, которую вы хотите условно выполнить один раз
if (needsToDoSomething) {
DoSomething();
needsToDoSomething = false;
}
однако, если вы работаете в двух потоках, оба потока могут проверить флаг и выполнить действие, прежде чем оба установят для флага значение false. Поэтому вы добавляете блокировку.
lock (Lock) {
if (needsToDoSomething) {
DoSomething();
needsToDoSomething = false;
}
}
однако, блокировка каждый раз, когда вы запускаете этот код, может быть медленной, поэтому вы решаете, давайте попробуем снять блокировку только тогда, когда нам это действительно нужно.
if (needsToDoSomething)
lock (Lock) {
if (needsToDoSomething) {
DoSomething();
needsToDoSomething = false;
}
}
Вы не можете удалить внутреннюю проверку, потому что, опять же, у вас есть проблема, что любая проверка, выполненная вне блокировки, может оказаться дважды в двух разных потоках.