Отмена цикла после фиксированного времени - PullRequest
0 голосов
/ 03 мая 2011

У меня есть поток, в котором у меня есть бесконечный цикл, делающий некоторые вещи в сети. Кажется, что я не получаю ответ каждый раз, когда делаю это, поэтому поток зависает на несколько секунд, что вызывает серьезные проблемы с моим программным обеспечением. Что мне нужно, так это какой-то «крайний срок» для цикла, если он занимает больше, чем (например, 100 мс), перезапустить снова.

private boolean active = true;
public void run(){

   while(active){
       //some network stuff e.g:
       dnshandler.reverselookup("8.8.8.8");
   }

}

(это не настоящий класс ... просто чтобы понять, что я имею в виду.)

Есть идеи, как с этим справиться?

Обновление: Я обработал его отдельной нитью, как это было предложено. На самом деле я использовал Callable, потому что мне нужно возвращаемое значение.

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        try {
            List<Future<String>> results = executor.invokeAll(Arrays.asList(new CallableClass()), 500), TimeUnit.MILLISECONDS);
            for (Future<String> current : results) {
                if (!current.isCancelled()) {
                    someValue = current.get();
                } else {
                    // timeout
                    executor.shutdownNow();
                }
            }

        } catch (Exception e) {
            //handle it!
            e.printStackTrace();
        }

Но проблема, с которой я сейчас сталкиваюсь, заключается в том, что executor.shutdownNow() не завершает зависшую задачу Callable (что является правильным поведением согласно Документации). Есть ли способ убить задачу исполнителя? (Я знаю, что это не чистое решение, но некоторые запросы обрабатываются библиотекой)

Ответы [ 5 ]

3 голосов
/ 03 мая 2011

Вы можете поместить свои сетевые компоненты в отдельный поток и запустить его на пару секунд, например:

int timeoutTime = ...
Runnable networkingStuff = ... // put the networking in here
Thread thread =new Thread(networkingStuff);
thread.start();
try {
    thread.join(timeoutTime);
    if(thread.isAlive()) {
        thread.interrupt();
    }
} catch (InterruptedException e) {
    // catch here the interruption
 }
2 голосов
/ 03 мая 2011

Google Guava's TimeLimiter может делать то, что вам нужно.

[TimeLimiter] создает прокси, которые накладывают ограничение по времени на вызовы методов для объекта прокси.

0 голосов
/ 03 мая 2011

Ваш бесконечный цикл загружает процессор.Попробуйте добавить задержку в 50 мс или около того, чтобы у процессора был небольшой перерыв для выполнения других задач.А еще лучше, запланируйте свою задачу, используя Timer с определенной задержкой и TimerTask.

0 голосов
/ 03 мая 2011

Вы должны прервать поток после истечения времени ожидания. Ознакомьтесь с java параллелизмом учебник .

0 голосов
/ 03 мая 2011

Извините, если это неправильно, поскольку я не являюсь Java-разработчиком, но с точки зрения общего программирования у вас должен быть метод, который может занять некоторое время, возвращая некоторую форму TimeoutException.

Вы можете перехватить это в цикле, и затем он автоматически перезапустится.

Это не проблема с циклом, тем более что вы вызываете метод (ы).

Альтернативный подход - запускать трудоемкие операции в отдельном потоке, чтобы ничего не зависало. Затем вы можете в любое время уведомить основной поток пользовательского интерфейса о завершении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...