Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
11
Добавлен:
27.03.2016
Размер:
29.7 Кб
Скачать

Лабораторна робота №6

Завдання: Розробити програму в якій створюється 3 потоки, 2 потоки блокуються на 10000 мс, а 3-й примусово розблоковує їх через 3000мс перший методом Interrupt, а через 7000мс розблоковує 2-й потік методом abort, потоки виводять повідомлення про розблокування і продовження роботи..

.

Теоретичні відомості: Interrupt и Abort

Заблокированный поток может быть преждевременно разблокирован двумя путями:

  • С помощью Thread.Interrupt.

  • С помощью Thread.Abort.

Это должно быть сделано из другого потока; ожидающий поток бессилен что-либо сделать в блокированном состоянии.

Interrupt

Вызов Interrupt для блокированного потока принудительно освобождает его с генерацией исключения ThreadInterruptedException, как показано в следующем примере:

class Program

{

static void Main()

{

Thread t = new Thread(delegate()

{

try

{

Thread.Sleep(Timeout.Infinite);

}

catch(ThreadInterruptedException)

{

Console.Write("Forcibly ");

}

Console.WriteLine("Woken!");

});

t.Start();

t.Interrupt();

}

}

Консольный вывод:

Forcibly Woken!

Прерывание потока освобождает его только от текущего (или следующего) ожидания, но не завершает поток (если, конечно, ThreadInterruptedException не останется необработанным).

Если Interrupt вызывается для неблокированного потока, поток продолжает исполнение до точки следующей блокировки, в которой и генерируется исключение ThreadInterruptedException. Это поведение освобождает от необходимости вставлять проверки:

if ((worker.ThreadState & ThreadState.WaitSleepJoin) > 0)

worker.Interrupt();

которые не являются потокобезопасными, так как могут быть прерваны другим потоком между оператором if и worker.Interrupt.

Вызов Interrupt без должных на то оснований таит в себе опасность, так как любой метод framework-а, или другой сторонний метод в стеке вызовов может получить его раньше, чем ваш код, которому он предназначался. Все, что для этого требуется – чтобы поток хотя бы кратковременно встал на простой блокировке или синхронизации доступа к ресурсу, и любой ждущий своего часа Interrupt тут же сработает. Если метод изначально не разрабатывался с учетом возможности такого прерывания (с соответствующим кодом очистки в блоках finally), объекты могут остаться в неработоспособном состоянии, или ресурсы будут освобождены не полностью.

Прерывать исполнение потока безопасно, если вы точно знаете, чем сейчас занят поток. Позже мы рассмотрим сигнальные конструкции, обеспечивающие такую возможность.

Abort

Блокированный поток также может быть принудительно освобожден при помощи метода Abort. Эффект аналогичен Interrupt, только вместо ThreadInterruptedException генерируется ThreadAbortException. Кроме того, это исключение будет повторно сгенерировано в конце блока catch (в попытке успокоить поток навеки), если только в блоке catch не будет вызван Thread.ResetAbort. До вызова Thread.ResetAbort ThreadState будет иметь значение AbortRequested.

Большое отличие между Interrupt и Abort состоит в том, что происходит, если их вызвать для неблокированного потока. Если Interrupt ничего не делает, пока поток не дойдет до следующей блокировки, то Abort генерирует исключение непосредственно в том месте, где сейчас находится поток – может быть, даже не в вашем коде. Аварийное завершение неблокированного потока может иметь существенные последствия

Соседние файлы в папке Semestr2