#java #spring #multithreading #deadlock #starvation
#java #весна #многопоточность #взаимоблокировка #голодание
Вопрос:
Предположим, у меня есть планировщик
@Component
public class Scheduler{
private static int counter = 0;
private synchronized void countIt(){
counter ;
}
@Scheduled(fixedDelay = 3000)
public void job1(){
countIt();
}
@Scheduled(fixedDelay = 6000)
public void job2(){
countIt();
}
}
Разные триггеры задачи в разных случаях будут вызывать countIt .
Когда два или более вызова задания выполняются одновременно, это приведет к голоданию.
Может ли кто-нибудь сказать мне, есть ли способ избежать этой ситуации?
Комментарии:
1. не похоже на случай взаимоблокировки
2. @AdamSkywalker реальный случай немного сложнее. У меня много потоков, вызывающих этот синхронизированный метод. Когда они вызывают метод в одно и то же время, произошла взаимоблокировка.
3. взаимоблокировка — это ситуация, когда поток 1 содержит ресурс A и нуждается в ресурсе B, а поток 2 содержит ресурс B и нуждается в ресурсе A. синхронизированный метод — это мьютекс, сам по себе он не может вызвать взаимоблокировку
4. возможно, ваш поток застрял внутри метода, и другие потоки ожидают его, но это не тупик
5. В лучшем случае это может привести к голоданию, но не к тупиковой ситуации.
Ответ №1:
Здесь нет взаимоблокировки!
Используйте ReetrantLock с справедливой политикой.если вы не знаете ReentrantLock, пожалуйста, погуглите его.
private final ReentrantLock lock = new ReentrantLock(true);
Комментарии:
1. Кажется, это то, что я ищу, позвольте мне сначала попробовать
Ответ №2:
Это не должно приводить к взаимоблокировке.
Взаимоблокировка вызвана тем, что один поток блокирует ресурс A
, а затем пытается заблокировать ресурс B
, в то время как другой поток блокирует ресурс B
, а затем пытается заблокировать ресурс A
. Существуют более сложные способы возникновения взаимоблокировки, но взаимоблокировки не могут происходить только с одной блокировкой.
В вашем случае существует только одна блокировка, поэтому взаимоблокировки нет.