Помимо исключений, таких как отображение памяти для драйверов, например, нет проблем для двух потоков, одновременно считывающих один и тот же адрес памяти. Однако может возникнуть проблема, когда один поток выполняет запись данных. В этом случае другим потокам может быть запрещено читать этот объект / данные.
Но проблема заключается не в одновременности записей (в любом случае, на самом низком электронном уровне они происходят одна за другой), проблема скорее в том, что объект / набор данных может потерять свои консистенция. Обычно используют section critic
для изоляции некоторого кода, который не может быть прочитан / записан одновременно другими потоками.
В сети есть много примеров, но рассмотрим следующее: price
является частным членом класса, скажем, Product, который также имеет 2 метода
public void setPrice(int value) {
price = value;
// -- point CRITIC --
price += TAX;
}
public int getPrice() {
return price;
}
setPrice (v) устанавливает цену продукта на v и корректирует ее с учетом НДС (программа должна иметь value += TAX; price = value
, но здесь дело не в этом: -)
Если поток A записывает цену 100, а TAX равен (фиксированному) 1, цена продукта, наконец, будет установлена равной 101. Но что произойдет, если поток B считывает цену через getPrice (), а поток A находится на point CRITIC
? Цена, возвращаемая B, пропустит НАЛОГ и будет неверной.
setPrice () должен находиться в критическом разделе (lock
), чтобы предотвратить любой доступ к объекту во время установки цены
lock(this)
{
price = value;
price += TAX;
}