Голодание синхронизированного метода планировщика Spring

#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 . Существуют более сложные способы возникновения взаимоблокировки, но взаимоблокировки не могут происходить только с одной блокировкой.

В вашем случае существует только одна блокировка, поэтому взаимоблокировки нет.