Рассмотрим эту программу более подробно. Сначала в ней создаются три класса. Первым из них оказывается классSumArray,в котором определяется методSumlt (),суммирующий элементы целочисленного массива. Вторым создается классMyThread,в котором используется статический объектsaтипаSumArray.Следовательно, единственный объект типаSumArrayиспользуется всеми объектами типаMyThread.С помощью этого объекта получается сумма элементов целочисленного массива. Обратите внимание на то, что текущая сумма запоминается в полеsumобъекта типаSumArray.Поэтому если методSumlt() используется параллельно в двух потоках, то оба потока попытаются обратиться к полюsum,чтобы сохранить в нем текущую сумму. А поскольку это может привести к ошибкам, то доступ к методуSumlt() должен быть синхронизирован. И наконец, в третьем классе,Sync,создаются два потока, в которых подсчитывается сумма элементов целочисленного массива.
Операторlockв методеSumlt() препятствует одновременному использованию данного метода в разных потоках. Обратите внимание на то, что в оператореlockобъектlockOnиспользуется в качестве синхронизируемого. Это закрытый объект, предназначенный исключительно для синхронизации. МетодSleep() намеренно вызывается для того, чтобы произошло переключение задач, хотя в данном случае это невозможно. Код в методеSumlt() заблокирован, и поэтому он может быть одновременно использован только в одном потоке. Таким образом, когда начинает выполняться второй порожденный поток, он не сможет войти в методSumlt() до тех пор, пока из него не выйдет первый порожденный поток. Благодаря этому гарантируется получение правильного результата.
Для того чтобы полностью уяснить принцип действия блокировки, попробуйте удалить из рассматриваемой здесь программы тело методаSumlt(). В итоге методSumlt() перестанет быть синхронизированным, а следовательно, он_может параллельно использоваться в любом числе потоков для одного и того же объекта. Поскольку текущая сумма сохраняется в полеsum,она может быть изменена в каждом потоке, вызывающем методSumlt(). Это означает, что если два потока одновременно вызывают методSumlt() для одного и того же объекта, то конечный результат получается неверным, поскольку содержимое поля sum отражает смешанный результат суммирования в обоих потоках. В качестве примера ниже приведен результат выполнения рассматриваемой здесь программы после снятия блокировки с метода Sumlt ().
Потомок #1 начат.
Сумма для потока Потомок #1 равна 2 9 Потомок #1 завершен.