#java
#java
Вопрос:
Я хочу принудительно запустить метод в течение указанного времени.
public Response run(Request req){
//method runImpl must run during specified interval of time(for example for 10 secs)
Response res = runImpl(req);
return response;
}
Каков наилучший способ сделать это?Спасибо!
Комментарии:
1. Реализация цикла ускорения? thedailywtf.com/Articles/The-Speedup-Loop.aspx
2. Что вы подразумеваете под «запуском в течение указанного интервала»? Должен ли он завершиться в течение этого интервала? Возврат только после этого интервала? Вызываться непрерывно в течение этого интервала?
3. Ваше использование слова «во время» здесь очень сбивает с толку.
4. Вы хотите, чтобы эта функция выполняла цикл с интервалом, останавливала процесс, пока не пройдет 10 секунд, или прерывалась, если прошло 10 секунд, а это не сделано?
5. Я имею в виду, что если интервал равен 10 секундам, функция прекращает выполнение по истечении этого периода времени и возвращает null. Может быть, я могу использовать класс Thread?
Ответ №1:
Попробуйте использовать это:
poolExecutor = new ScheduledThreadPoolExecutor(1);
poolExecutor.scheduleAtFixedRate(
new YourRunable(), startFrom/*10*/, startEvery/*5*/, TimeUnit.SECONDS);
Комментарии:
1. Да, это оно . Вот что я имел в виду!
2. это не требует, чтобы запускаемый запускался максимум в течение X секунд — он предназначен для запуска запускаемого запуска через N секунд и повторного вызова каждые M секунд
Ответ №2:
runImpl должен возвращать логическое значение, чтобы этот код работал. Вероятно, вам понадобится это в новом потоке (базовых руководств предостаточно), если вы не хотите, чтобы ваша программа остановилась до ее завершения.
public Response run(Request req){
long lasttime=Sys.getTime();
int i=0;
while(i<10){
if(Response res = runImpl(req);){
return response;
}
if((Sys.getTime-lasttime)>1000){
i ;
lasttime=Sys.getTime();
}
}
return null;
Это выполняется каждый момент работы процессора, если вы хотите, чтобы он выполнялся с интервалом, а также в течение 10 секунд, используйте:
public Response run(Request req){
long lasttime=Sys.getTime();
int i=0;
for(int i; i<(10000/yourchoiceinterval); i ){
if(Response res = runImpl(req);){
return response;
}
if((Sys.getTime-lasttime)>1000){
lasttime=Sys.getTime();
}
}
return null;
Ответ №3:
Лучшим методом было бы сделать вашу работу порциями соответствующего размера, чтобы каждый фрагмент можно было выполнить, скажем, за 1 секунду. Таким образом, в конце каждого фрагмента вы можете проверить, прошло ли время.
Если ваша работа связана с работой ввода-вывода, которая может блокироваться на неопределенное время, попробуйте использовать прерываемые методы (которые могут быть прерваны вызовом Thread.interrupt()
) или методы, которые принимают явное максимальное время выполнения от вызывающего.
Или вы можете делегировать работу ввода-вывода какому-либо выделенному потоку и проверять ее ход в отдельном потоке, а также действовать соответствующим образом при превышении времени выполнения.
Комментарии:
1. Что делать, если во время выполнения некоторого фрагмента функция «зависает»?
2. @Martin Я предположил, что нет шагов, которые могут «зависнуть» с какой-либо разумной вероятностью. Если есть такие шаги, например, сетевой ввод-вывод, используйте один поток для ввода-вывода, а другой — для проверки хода ввода-вывода и прерывания ввода-вывода при необходимости.
Ответ №4:
Вы можете запустить новый поток, который вызывает только ваш метод, и перевести его в спящий режим по истечении созданного вами таймера. Таким образом, вы не можете гарантировать, что цикл метода завершен до приостановки, но делает свое дело без необходимости изменять метод. Чтобы вы могли достичь циклов, просто поместите эту логику сна в цикл потока. Просто не забудьте разбудить поток
Могут быть десятки реализаций, поскольку вы недостаточно ясно объяснили.