#java #multithreading #wait
#java #многопоточность #подождите
Вопрос:
Ситуация такова, что есть два потока, которые ожидают друг друга для некоторого события. и это тупик. В этом случае я хочу, чтобы один поток прекратил ожидание и выдал исключение, чтобы другой поток мог продолжить свою задачу. логически я могу это сделать, но есть ли какой-либо другой способ выполнить эту задачу? что я сделал :
boolean flag=true;
run(){
synchronized(this){
if(flag){
boolean flag=false;
wait(1500);
}else{
throw new Exception();
}
}
}
дополнительное описание:
например
Один поток хочет добавить нового клиента (CustomerA) в таблицу customer, но
он обнаружил, что ThreadB уже запустил этот процесс, поэтому ThreadA ожидает завершения ThreadB (поскольку идентификатор клиента требуется для внешнего ключа в другой таблице)
ThreadB, хотя и завершил вставку в CustomerA, но ему необходимо вставить некоторые новые данные о городе для вставки в таблицу городов, но он ожидает, поскольку этот процесс уже запущен ThreadA
И оба ожидают завершения друг друга
Комментарии:
1. Да, удачи в поиске решения тупиковой ситуации.
2. 1 Кажется, что JVM должна иметь эту опцию. В конце концов, вы получаете отчет о взаимоблокировках, когда создаете дамп потока, так что уже есть код для обнаружения взаимоблокировок. Может быть какое-то (необязательное) средство для периодической проверки и разрешения взаимоблокировок (точно так же, как это делают СУБД).
3. @Thilo — Я не совсем понимаю.. Как событие может рассматриваться как ресурс?. И как 2 потока окажутся в тупике на основе события?. ожидая друг друга для некоторого события . Они ничего не содержат. Они просто ждут..
4. @TheLostMind добавил описание примера сценария.
5. У вас нет тупиковой ситуации. У вас просто есть
wait
вызов, но нет никакого распознаваемого условия, которого вы ждете. Обычно другой поток вызывал бы,notify
чтобы разрешитьwait
завершение, но это должно быть дополнено проверяемым условием, которое ожидающий поток должен проверить (и перепроверить послеwait
), и поток уведомления должен измениться на выполненный. Единственное, что похоже на условие, — это вашboolean
флаг, но поскольку ваш ожидающий поток сам изменяет этот флаг перед ожиданием, все это не имеет смысла.
Ответ №1:
Способ избежать всех строгих взаимоблокировок его типа — это всегда требовать одни и те же блокировки в одном и том же порядке. В вашем примере оба потока должны сначала обновить таблицу городов, а затем таблицу пользователей, или они оба должны сделать это наоборот. Тогда взаимоблокировка не может возникнуть.
Комментарии:
1. спасибо за ценный вклад. Но это пример сценария, и в реальном сценарии проблема в том, что я не могу поддерживать порядок, например, у клиента A может быть другой CustomerC (поэтому рекурсивно вызывайте клиента), а у клиента B нет другого клиента.
2. Это не имеет значения. Обнаружение и восстановление из взаимоблокировок чрезвычайно сложно. Для их предотвращения может потребоваться небольшая реорганизация вашего приложения, но это определенно правильное решение. Просто рассматривайте это как требование и кодируйте соответственно.