tgoop.com/unsafecsharp/239
Create:
Last Update:
Last Update:
if lock if
У меня в BECS очень много всяких вариантов локов, например, для ресайзов вида:
if (obj.isCreated == false) {
obj = new Obj();
}
Но поскольку мне нужно многопоточность, самый простой вариант обернуть это в лок:
lock (lockObj) {
if (obj.isCreated == false) {
obj = new Obj();
}
}
Но поскольку операция создания объекта происходит крайне редко (тут даже скорее лучше бы подошел пример с ресайзом массива), то какой смысл тратить перф на блокировку? Никакого.
if (obj.isCreated == false) {
lock (lockObj) {
if (obj.isCreated == false) {
obj = new Obj();
}
}
}
Получается такая матрешка, но давайте резберемся что будет для нескольких потоков:
1. Поток №1 входит в условие if (obj.isCreated == false);
2. Поток №2 тоже может успеть войти в это условие;
3. Поток №1 блокирует объект;
4. Поток №2 ожидает снятия блокировки;
5. Поток №1 создает объект и записывает его;
6. В этом месте любое количество других потоков может войти в метод и уже использовать наш объект;
7. Поток №1 выходит из блокировки, освобождая поток №2
8. Поток №2 проверяет еще раз if (obj.isCreated == false) и оказывается, что ничего делать уже не нужно.
Таким образом если какая-то операция происходит довольно редко, то такая реализация ленивой инициализации в многопоточной среде увеличит производительность.
Естественно, я не использую конструкцию lock, заменяя ее CompareExchange, но для примера привожу именно lock.
Важное уточнение: isCreated = true вашего объекта в конструкторе должен идти последним, т.е. когда мы уже можем использовать объект.
#multithreading #csharp #lock
BY Unity: Всё, что вы не знали о разработке
Share with your friend now:
tgoop.com/unsafecsharp/239