powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Задача с таймерами
25 сообщений из 33, страница 1 из 2
Задача с таймерами
    #38812993
JulT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет. Есть заказ, есть исполнитель заказа. Когда заказ создается, запускается таймер, который в течении 5 минут ищет исполнителя. Если в течении этого времени исполнитель не найден, заказ отменяется. Заказов одновременно может быть много и получается, что под каждый из этих заказов должен запускаться отдельный таймер. Я так понимаю каждый такой таймер должен создаваться в отдельном потоке... В общем, как решаются подобные задачи? Может быть для этих целей есть хорошая библиотека, поделитесь опытом, пожалуйста. Спасибо
...
Рейтинг: 0 / 0
Задача с таймерами
    #38813020
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет смысла создавать каждый таймер в своём потоке. Так как "убить задачу" процесс, быстрый, то одного потока хватит с головой.
На худой конец, сконфигуряете на пул из 2х потоков
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

Запускается процесс, для ней сабмитится runnable в ScheduledExecutorService. При запуске runable проверяет, если его процесс ещё активет, то убивает его.
...
Рейтинг: 0 / 0
Задача с таймерами
    #38813143
JulT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczНет смысла создавать каждый таймер в своём потоке. Так как "убить задачу" процесс, быстрый, то одного потока хватит с головой.
На худой конец, сконфигуряете на пул из 2х потоков
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

Запускается процесс, для ней сабмитится runnable в ScheduledExecutorService. При запуске runable проверяет, если его процесс ещё активет, то убивает его.
Спасибо, это именно то, что нужно. Но я не могу понять один момент. Заказ я должна убивать в двух случаях: 1) по таймауту (прошло 5 минут никто не откликнулся), 2) когда статус заказа в базе данных поменялся с waiting на in_progress. С пунктом 1 все вроде понятно, а вот со 2 нет. Грубо говоря:
Для первого пункта:
Код: java
1.
2.
3.
4.
5.
6.
 scheduler.schedule(new Runnable() {
            public void run() {
                beeperHandle.cancel(true);
                System.out.println("cancel");
            }
        }, 60 * 60, SECONDS);


А для второго как? Мне ведь нужно сопоставить как-то айдишник заказа с потоком, нужно это для того, чтобы пока крутится таймер лезть в базу, проверять статус и если он in_progress (т.е. его взяли на исполнение) - делать beeperHandle.cancel(true);
Не совсем понимаю как этот момент разрулить
...
Рейтинг: 0 / 0
Задача с таймерами
    #38813167
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JulT,

Жесть какая. В методе, который меняет статус, делаете проверку и вызываете отмену.
...
Рейтинг: 0 / 0
Задача с таймерами
    #38813180
JulT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczJulT,

Жесть какая. В методе, который меняет статус, делаете проверку и вызываете отмену.

это понятно, я к тому, что не отвалятся ли при такой отмене другие таймеры связанные с другими заказами? ладно, нужно почитать детально про принцип работы ScheduledExecutorService, я впервые с ним сталкиваюсь
спасибо
...
Рейтинг: 0 / 0
Задача с таймерами
    #38813200
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz Жесть какая. В методе, который меняет статус, делаете проверку и вызываете отмену.
На сколько я понял девушку, метод который меняет сатус работает в БД.
Оттуда тяжело убить процесс.

Хотя возможно это сам процесс нашедший исполнителя, тогда какие, спрашивается, сложности самому закончится?
...
Рейтинг: 0 / 0
Задача с таймерами
    #38813215
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Арсеньев На сколько я понял девушку, метод который меняет сатус работает в БД.

Этого мы знать не можем.

Сергей Арсеньев Оттуда тяжело убить процесс.

Не так уж и тяжело. Вешаем триггер. Кидаем событие. Ловим событие, отменям процесс по id.

Сергей АрсеньевХотя возможно это сам процесс нашедший исполнителя, тогда какие, спрашивается, сложности самому закончится?
Сложностей никаких нет. Странно, конечно, что вопрос начинается про таймеры, а продолжается в стиле "ну и как же мне тогда сделать что-то совершенно другое".
...
Рейтинг: 0 / 0
Задача с таймерами
    #38823732
JulT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть одна непонятная проблема:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
TestTask testTask = new TestTask();
final ScheduledFuture<?> testHandle = scheduler.scheduleAtFixedRate(testTask, 0, 1, SECONDS);

@Component
public class TestTask implements Runnable{
    private static final Logger LOGGER = LoggerFactory.getLogger(TestTask.class);

    @Autowired
    HumanRepository humanRepository;

    @Override
    public void run() {
       System.out.println("run task");
    }


Запускаю, каждую секунду в консоли выводится run task, все отлично. Но! Как только добавляю в метод run строчку:

Код: java
1.
Human hman = humanRepository.findOne(humanId);

(humanId=4)
Код: java
1.
2.
3.
4.
5.
6.
@Override
    public void run() {
       System.out.println("run task");
       Human hman = humanRepository.findOne(humanId);
       System.out.println("after");
    }


after никогда при этом не выводится, т.е. зависает на findOne. Делаю в другом классе вызов findOne, все работает. С чем это может быть связано? Спасибо
...
Рейтинг: 0 / 0
Задача с таймерами
    #38823736
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JulT, при некотором стечении обстоятельств твой сервер задач может рухнуть. Нужны какие-то
limitations. Лучше всего - очередь задачь ожидающих своей диспетчеризации.
...
Рейтинг: 0 / 0
Задача с таймерами
    #38823858
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
off
очень интересно, как _ищется_ исполнитель 5 минут на гигагерцевом ядре процессора? )
...
Рейтинг: 0 / 0
Задача с таймерами
    #38823863
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если изменить термин на "заказ висит 5 минут в .....", то можно проходя обычным JOB раз минуту снимать статус протухшего заказа.
...
Рейтинг: 0 / 0
Задача с таймерами
    #38823871
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JulTafter никогда при этом не выводится, т.е. зависает на findOne.
Та, нет же не зависает. Сколько можно рассказывать, что это кривизна в Excecutor, которые тихо кушают все исключения и даже на консоль их не выводят.
А исключение вылетает, скорее всего, из-за того что в этом потоке репозиторий не работает, так как потом не связан с контейнером. Соответсвенно чего-то в своих ThreadLocal найти не может.
...
Рейтинг: 0 / 0
Задача с таймерами
    #38823872
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123off
очень интересно, как _ищется_ исполнитель 5 минут на гигагерцевом ядре процессора? )
Да при чём тут гигагерцы. Если там в БД хранимка чего-то долго ищет.
...
Рейтинг: 0 / 0
Задача с таймерами
    #38823892
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonPetro123off
очень интересно, как _ищется_ исполнитель 5 минут на гигагерцевом ядре процессора? )
Да при чём тут гигагерцы. Если там в БД хранимка чего-то долго ищет.
off
расскажи алгоритм поиска
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824002
JulT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczJulTafter никогда при этом не выводится, т.е. зависает на findOne.
Та, нет же не зависает. Сколько можно рассказывать, что это кривизна в Excecutor, которые тихо кушают все исключения и даже на консоль их не выводят.
А исключение вылетает, скорее всего, из-за того что в этом потоке репозиторий не работает, так как потом не связан с контейнером. Соответсвенно чего-то в своих ThreadLocal найти не может.
Вы абсолютно правы, вылетает exception, еле отловила его. Вся проблема в том, что не инжектится бин. Создала новую тему, а нужно было здесь продолжить. Повторюсь:
Почему testRepository в классе:
Код: java
1.
2.
3.
4.
5.
@Service("autoSearch")
public class AutoSearch implements Runnable{

    @Autowired
    TestRepository testRepository;

всегда = null
В этом же пакете рядом лежит другой класс:
Код: java
1.
2.
3.
4.
5.
@Service("test")
public class B {

    @Autowired
    TestRepository testRepository;


и в нем инъекция проходит успешно.
Если я правильно понимаю, то причина в implements Runnable. Помогите разобраться. Спасибо
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824015
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
причина в том, что спринг контейнер понятия не имеет о вашем потоке
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824103
JulT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник,

Да, спасибо, уже разобралась. Я вызываю контекст и явно вызываю getBean. Единственное, мне не нравится, что у меня дваждый вызывается конфигурация, первый раз при запуске приложения, второй раз при явном вызове метода через ctx.getBean .... Этого можно как-то избежать?
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824189
DDiver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JulT,

что значит вызывается? два раза инициализируется контекст?
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824351
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczJulTafter никогда при этом не выводится, т.е. зависает на findOne.
Та, нет же не зависает. Сколько можно рассказывать, что это кривизна в Excecutor, которые тихо кушают все исключения и даже на консоль их не выводят.


И как тогда бороться с этой проблемой? Как отлавливать исключения?
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824389
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
try{

} catch() {

} finally
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824439
JulT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DDiverJulT,

что значит вызывается? два раза инициализируется контекст?
да
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824455
JulT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не могу понять что происходит
добавляю ctx в:
Код: java
1.
2.
3.
@Service("autoSearch")
public class AutoSearch implements Runnable{
private ApplicationContext ctx = new ClassPathXmlApplicationContext("META-INF/application-context.xml");


запускаю проект, в консоль валятся логи инициализации контекста, причем постоянно, в итоге все заканчивается исключением: to many connection. Как быть?
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824476
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JulT,
так не годится, контекст следует инициализировать только 1 раз. Например, при старте приложения. Или используя синглетон. Тут много разных способов, например такой:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
public class AppContextFactory {
	private static class SingletonHolder { 
		private static ApplicationContext ctx = new ClassPathXmlApplicationContext("META-INF/application-context.xml");
	}
	public static ApplicationContext getInstance() {
		return SingletonHolder.ctx;
	}
}


Дальше обращаемся к нему только через статический метод AppContextFactory.getInstance()
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824552
JulT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraJulT,
так не годится, контекст следует инициализировать только 1 раз. Например, при старте приложения. Или используя синглетон. Тут много разных способов, например такой:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
public class AppContextFactory {
	private static class SingletonHolder { 
		private static ApplicationContext ctx = new ClassPathXmlApplicationContext("META-INF/application-context.xml");
	}
	public static ApplicationContext getInstance() {
		return SingletonHolder.ctx;
	}
}


Дальше обращаемся к нему только через статический метод AppContextFactory.getInstance()
Спасибо огромное. Сделала так: в application-context.xml добавила строчку:
Код: java
1.
<bean id="applicationContextFactory" class="ru.test.utils.context.AppContextFactory"></bean>


Далее:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
@Service("autoSearch")
public class AutoSearch implements Runnable{
@Autowired
	TestRepository testRepository;

	private TestRepository getTestRepository() {
		if (testRepository==null) {
			ApplicationContext ctx = AppContextFactory.getInstance();
			testRepository = ctx.getBean(TestRepository.class);
		}
		return testRepository;
	}


Все отлично работает, но все же мой контекст вызывается дважды. Первый раз при старте приложения, второй раз при вызове getTestRepository(). Этого можно как-то избежать?
...
Рейтинг: 0 / 0
Задача с таймерами
    #38824574
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JulT,
при старте приложения тоже надо вызывать метод AppContextFactory.getInstance(), это надо делать везде в приложении, где требуется получить контекст. На то он и синглетон
...
Рейтинг: 0 / 0
25 сообщений из 33, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Задача с таймерами
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]