2014-12-06 2 views
2

Общий вопрос для моего вопроса состоял в том, как мы обнаруживаем, что какой-либо вызов функции длился слишком долго, так что мы хотим его прекратить?Как ограничить время выполнения потока и завершить его, если он работает слишком долго?

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

class MyThread extends Thread 
{ 
    public void run() 
    { 
    someFunction(); 
    } 
} 

И сказать SomeFunction может быть:

public void someFunction() 
{ 
    // Unknown code that could take arbitrarily long time. 
} 

В приведенном выше коде someFunction() может занять некоторое время, чтобы закончить или использовать его навсегда, поэтому скажите, что я хочу остановить его, когда он слишком долго.

Однако в реализации потока Java, по-видимому, я не могу использовать общую переменную или любую временную метку в потоке, так что поток будет иметь смысл времени, потому что someFunction() смешно атомизирует и такой код проверки на отметку времени может идти только после someFunction, что становится бесполезным, поскольку в момент выполнения кодирования некоторая функция уже выполнена.

ПРИМЕЧАНИЕ: Я также хочу сделать это с someFunction(), являющимся агностиком. То есть someFunction() не должен беспокоиться о том, сколько времени он запускает. Он просто не должен об этом знать.

Может ли кто-нибудь дать представление о том, как я могу выполнить эту функцию?

+0

Вы говорите о тупике? Я не ожидаю, что люди будут писать код, как показано выше. Дайте нам точный сценарий. – SMA

+0

@almasshaikh В замках нет ничего. Я просто спрашиваю, хочу ли я убедиться, что один поток не будет работать слишком долго или мы его убьем, как нам это сделать? – OneZero

+0

используйте другой запланированный поток, который запускает ваш поток, начинающийся с ссылки на поток в нем, и просыпается, скажем, через час, и если он все еще прерывает его (если ваш поток реагирует на прерывание). – SMA

ответ

2

Я бы использовал ExecutorService для запуска потока. Затем я вернусь Future и воспользуюсь get() с таймаутом, чтобы отменить его.

ExecutorService es = Executors.newFixedThreadPool(1); // You only asked for 1 thread 
Future<?> future = es.submit(new Mythread()); 
try { 
    future.get(timeout, TimeUnit.SECONDS); // This waits timeout seconds; returns null 
} catch(TimeoutException e) { 
    future.cancel(true); 
} 
+0

Это заблокировало бы ожидание будущего, но – NilsH

+1

'future.cancel (true)' будет бесполезным, если функция не написана для правильной обработки (а не только для улова) InterruptedExceptions и interruptts вообще. – VGR

+0

Скажите, что есть 2 темы. Скажем, я хочу, чтобы каждый из потоков индивидуально не занимал больше 10 секунд. Скажем, 1-я нить занимает 10, 1-е будущее.get() будет ждать 10 секунд. Скажем, 2-й поток все еще работает на этом этапе, future.get() на 2-й будет ждать еще 10 секунд и, следовательно, полностью 20-е. Как этого избежать? – user104309