Thread.Sleep(10); // разрешить переключение задач
}
return sum;
}
}
}
class MyThread {
public Thread Thrd;
int[] a;
int answer;
Создать один объект типа SumArray для всех
Экземпляров класса MyThread.
static SumArray sa = new SumArray();
Сконструировать новый поток,
public MyThread(string name, int [ ] nums) {
a = nums;
Thrd = new Thread(this.Run);
Thrd.Name = name;
Thrd.Start(); // начать поток
}
Начать выполнение нового потока,
void Run() {
Console.WriteLine(Thrd.Name + " начат.");
answer = sa.SumIt(a);
Console.WriteLine("Сумма для потока " + Thrd.Name +
" равна " + answer);
Console.WriteLine(Thrd.Name + " завершен.");
}
}
class Sync {
static void Main() {
int[] a = {1, 2, 3, 4, 5};
MyThread mt1 = new MyThread ("Потомок #1", a);
MyThread mt2 = new MyThread("Потомок #2", a);
mt1.Thrd.Join();
mt2.Thrd.Join() ;
}
}
Ниже приведен результат выполнения данной программы, хотя у вас он может оказаться несколько иным.
Потомок #1 начат.
Потомок #2 начат.
Текущая сумма для потока Потомок #1 равна 1
Текущая сумма для потока Потомок #1 равна 3
Текущая сумма для потока Потомок #1 равна 6
Текущая сумма для потока Потомок #1 равна 10
Текущая сумма для потока Потомок #1 равна 15
Сумма для потока Потомок #1 равна 15
Потомок #1 завершен.
Текущая сумма для потока Потомок #2 равна 1
Текущая сумма для потока Потомок #2 равна 3
Текущая сумма для потока Потомок #2 равна 6
Текущая сумма для потока Потомок #2 равна 10
Текущая сумма для потока Потомок #2 равна 15
|
|
Сумма для потока Потомок #2 равна 15
Потомок #2 завершен.
Как следует из приведенного выше результата, в обоих потоках правильно подсчитывается сумма, равная 15.
Рассмотрим эту программу более подробно. Сначала в ней создаются три класса. Первым из них оказывается класс SumArray, в котором определяется метод SumIt(), суммирующий элементы целочисленного массива. Вторым создается класс MyThread, в котором используется статический объект sa типа SumArray. Следовательно, единственный объект типа SumArray используется всеми объектами типа MyThread. С помощью этого объекта получается сумма элементов целочисленного массива. Обратите внимание на то, что текущая сумма запоминается в поле sum объекта типа SumArray. Поэтому если метод SumIt() используется параллельно в двух потоках, то оба потока попытаются обратиться к полю sum, чтобы сохранить в нем текущую сумму. А поскольку это может привести к ошибкам, то доступ к методу SumIt() должен быть синхронизирован. И наконец, в третьем классе, Sync, создаются два потока, в которых подсчитывается сумма элементов целочисленного массива.
Оператор lock в методе SumIt() препятствует одновременному использованию данного метода в разных потоках. Обратите внимание на то, что в операторе lock объект lockOn используется в качестве синхронизируемого. Это закрытый объект, предназначенный исключительно для синхронизации. Метод Sleep() намеренно вызывается для того, чтобы произошло переключение задач, хотя в данном случае это невозможно. Код в методе SumIt() заблокирован, и поэтому он может быть одновременно использован только в одном потоке. Таким образом, когда начинает выполняться второй порожденный поток, он не сможет войти в метод SumIt() до тех пор, пока из него не выйдет первый порожденный поток. Благодаря этому гарантируется получение правильного результата.
|
|
Для того чтобы полностью уяснить принцип действия блокировки, попробуйте удалить из рассматриваемой здесь программы тело метода SumIt(). В итоге метод SumIt() перестанет быть синхронизированным, а следовательно, он может параллельно использоваться в любом числе потоков для одного и того же объекта. Поскольку текущая сумма сохраняется в поле sum, она может быть изменена в каждом потоке, вызывающем метод SumIt(). Это означает, что если два потока одновременно вызывают метод SumIt() для одного и того же объекта, то конечный результат получается неверным, поскольку содержимое поля sum отражает смешанный результат суммирования в обоих потоках. В качестве примера ниже приведен результат выполнения рассматриваемой здесь программы после снятия блокировки с метода SumIt().
|
|
Потомок #1 начат.
Потомок #2 начат.
Дата добавления: 2019-02-12; просмотров: 252; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!