Критическая секция - это секция кода, где, если более чем один поток будет делать это одновременно, они могут мешать друг другу, что может привести к неверному результату или другой неисправности. Представьте себе простую банковскую процедуру обработки чека:
doCheck (writer, recipient, amount) {
if (amount < 0) return DIAF;
balance = getBalance( writer );
if (balance < amount) return NSF;
setBalance( recipient, getBalance(recipient) + amount );
setBalance( writer, balance - amount );
}
Теперь представьте, что мой баланс составляет 11 000 долларов, и я написал два чека:
John, ColumbiaHouse, $0.01
John, MrsJohn, $10,000
Теперь наш банк обрабатывает так много проверок, что программист «ас» DonaldJavaSlump добавляет многопоточность, потому что производительность - но он не знает о критических секциях, поэтому поток 1 начинает обрабатывать первую проверку:
if (amount < 0) return DIAF; // (0.01 < 0)? OK
balance = getBalance(John) // $11,000
if (balance < amount) return NSF; // (11,000 < 0.01?) OK
setBalance( ColumbiaHouse, ... // KaChing! ColumbiaHouse gets paid
и теперь поток 2 запускается через ту же часть кода, обрабатывающую вторую проверку:
if (amount < 0) return DIAF; // (10,000 < 0)? OK
balance = getBalance( John ); // $11,000 (still!)
if (balance < amount) return NSF; // (11,000 < 10,000?) OK
setBalance( MrsJohn, ... // KaChing! MrsJohn gets paid
setBalance( John, balance - amount ); // my balance is now $1,000 :(
и затем поток 1 подходит к завершению своей работы:
setBalance( John, balance - amount ); // now balance is $10,999.99!!! :)
Теперь Джон и миссис Джон очень счастливы и отправляются в круиз со свободными деньгами !!