|
Spec-Zone .ru
спецификации, руководства, описания, API
|
Считайте простой class вызванным Counter
class Counter {
private int c = 0;
public void increment() {
c++;
}
public void decrement() {
c--;
}
public int value() {
return c;
}
}
Counter разрабатывается так, чтобы каждый вызов increment добавит 1 к c, и каждый вызов decrement вычтет 1 из c. Однако, если a Counter на объект ссылаются от многократных потоков, интерференция между потоками может предотвратить это как ожидалось.
Интерференция происходит когда две операции, работающие в различных потоках, но действующие на те же самые данные, чередование. Это означает, что эти две операции состоят из многократных шагов, и последовательностей перекрытия шагов.
Это не могло бы казаться возможным для операций на экземплярах Counter чередоваться, начиная с обеих операций на c единственные, простые операторы. Однако, даже простые операторы могут преобразовать в многократные шаги виртуальной машиной. Мы не будем исследовать определенные шаги, которые делает виртуальная машина — достаточно знать что единственное выражение c++ может анализироваться в три шага:
c.c.Выражение c-- может анализироваться тот же самый путь, за исключением того, что второй шаг постепенно уменьшается вместо инкрементов.
Предположите, что Поток A вызывает increment в приблизительно том же самом Потоке времени B вызывает decrement. Если начальное значение c 0, их чередованные действия могли бы следовать за этой последовательностью:
Распараллельте результат А, теряется, перезаписывается Потоком B. Это определенное чередование является только одной возможностью. При различных обстоятельствах это мог бы быть результат Б Потока, который теряется, или не могло быть никакой ошибки вообще. Поскольку они непредсказуемы, распараллеливают интерференционные ошибки, может быть трудным обнаружить и фиксировать.