Тупик без цикла
Если я нарисую график, который символизирует все возможные вызовы функций блокировки (синхронизированные методы Java), и у меня нет цикла в этом графике, могу ли я быть уверен, что взаимоблокировки невозможны. Разве петрицы не работают так?
Я не ищу ответы вроде этого: Используйте какой-нибудь монстр фреймворк, бла-бла
Я хочу обработать мою многопоточность синхронизированными методами.
РЕДАКТИРОВАТЬ1: указанные стрелки символизируют, если один класс вызывает какой-либо синхронизированный метод другого класса. РЕДАКТИРОВАНИЕ2: см. Пример здесь, показывающий цикл
3 ответа
Рассмотрим:
private static final Semaphore foo = new Semaphore(1);
private static final Semaphore bar = new Semaphore(1);
private static void one() throws InterruptedException {
foo.acquire();
bar.acquire();
bar.release();
foo.release();
}
private static void two() throws InterruptedException {
bar.acquire();
foo.acquire();
foo.release();
bar.release();
}
См. Http://pastebin.com/QfK5ZByj для работоспособного примера. Это довольно быстро для меня.
Нет, этого недостаточно. Предположим, вам нужны потоки: A и B. A вызывает метод m1 объекта o1, который вызывает метод m1 объекта o2. Поток B вызывает метод m2 объекта o2, который вызывает метод m2 объекта o1. Предположим, что все методы синхронизированы. Теперь есть одновременные исполнения A и B, которые приводят к тупикам. Хотя между методами нет отношения циклического вызова.
Это домашнее задание?
Даже с вашей правкой относительно класса этого недостаточно, потому что вы можете закрыть цикл с помощью несинхронизированного вызова метода.
Некоторые методы могут блокироваться без synchronized
ключевое слово Это относится ко многим методам в пакете java.util.concurrent
например. Вы также должны принять во внимание synchronized
блоки внутри методов.
Если рассматривать только синхронизированные методы, в вызовах методов могут возникать тупики без цикла, поскольку синхронизированные методы используют экземпляр объекта в качестве монитора. Например, если у вас есть два объекта A и B, каждый с синхронизированными методами 1() и 2(). Если A.1() вызывает B.1(), а B.2 () вызывает A.2 (), хотя в методах нет цикла, если поток вызывает B.2()
в то же время другие звонки A.1()
тогда существует тупиковый риск.