Программирование на JAVA

Навигация

Лекция 1. Что такое Java? История создания

Лекция 2. Основы объектно-ориентированного программирования

Лекция 3. Лексика языка

Лекция 4. Типы данных

Лекция 5. Имена. Пакеты

Лекция 6. Объявление классов

Лекция 7. Преобразование типов

Лекция 8. Объектная модель в Java

Лекция 9. Массивы

Лекция 10. Операторы и структура кода. Исключения

Лекция 11. Пакет java.awt

Лекция 12. Потоки выполнения. Синхронизация

Лекция 13. Пакет java.lang

Лекция 14. Пакет java.util

Лекция 15. Пакет java.io

Лекция 16. Введение в сетевые протоколы

Реклама :





public static void main(String s[]) {

// Создаем два потока, которые будут // конкурировать за доступ к объектам one и two Thread t1 = new Thread() { public void run() {

// Блокировка первого объекта synchronized(one) { Thread. yield();

// Блокировка второго объекта synchronized (two) {

System, out. printlnf'Success!");

}

}

}

};

Thread t2 = new Thread() { public void run() {

// Блокировка второго объекта synchronized(two) { Thread.yield();

// Блокировка первого объекта synchronized (one) {

System, out. println("Success!");

}

}

}

};

// Запускаем потоки t1 .startO; t2.start();

}

}

Если запустить такую программу, то она никогда не закончит свою работу. Обратите внимание на вызовы метода yield() в каждом потоке. Они гарантируют, что когда один поток выполнил первую блокировку и переходит к следующей, второй поток находится в таком же состоянии. Очевидно, что в результате оба потока "замрут", не смогут продолжить свое выполнение. Первый поток будет ждать освобождения второго объ­екта, и наоборот. Именно такая ситуация называется "мертвой блокиров­кой", или deadlock. Если один из потоков успел бы заблокировать оба объекта, то программа успешно бы выполнилась до конца. Однако мно­гопоточная архитектура не дает никаких гарантий, как именно потоки бу­дут выполняться друг относительно друга. Задержки (которые в примере моделируются вызовами yield()) могут возникать из логики программы (необходимость произвести вычисления), действий пользователя (не сра­зу нажал кнопку "ОК."), занятости ОС (из-за нехватки физической опера­тивной памяти пришлось воспользоваться виртуальной), значений при­оритетов потоков и так далее.

В Java нет никаких средств распознавания или предотвращения си­туаций deadlock. Также нет способа перед вызовом синхронизированно­го Метода узнать, заблокирован ли уже объект другим потоком. Програм­мист сам должен строить работу программы таким образом, чтобы нераз­решимые блокировки не возникали. Например, в рассмотренном примере Достаточно было организовать блокировки объектов в одном порядке (все-^ сначала первый, затем второй) - и программа всегда выполнялась бы Успешно.

Опасность возникновения взаимных блокировок заставляет с осо-\  нНым вниманием относиться к работе с потоками. Например, важно п°мнить, что если у объекта потока был вызван метод sleep(