그래서 궁금합니다. 스레드의 최대 실행 시간 설정은 어떻게 처리합니까? 스레드 풀에서 실행할 때?스레드의 최대 실행 시간을 처리하는 가장 좋은 방법 (Java)
몇 가지 기술이 있지만 필자는 결코 그 기술에 만족하지 않습니다. 그래서 나는 그들이 어떻게 그것에 대해 가는지 지역 사회에 물어볼 것이라고 생각합니다.
그래서 궁금합니다. 스레드의 최대 실행 시간 설정은 어떻게 처리합니까? 스레드 풀에서 실행할 때?스레드의 최대 실행 시간을 처리하는 가장 좋은 방법 (Java)
몇 가지 기술이 있지만 필자는 결코 그 기술에 만족하지 않습니다. 그래서 나는 그들이 어떻게 그것에 대해 가는지 지역 사회에 물어볼 것이라고 생각합니다.
일반적으로 스레드 코드에서 컨트롤 개체를 정기적으로 폴링합니다. 뭔가 같은 :
interface ThreadControl {
boolean shouldContinue();
}
class Timer implements ThreadControl {
public boolean shouldContinue() {
// returns false if max_time has elapsed
}
}
class MyTask implements Runnable {
private tc;
public MyTask(ThreadControl tc) {
this.tc = tc;
}
public void run() {
while (true) {
// do stuff
if (!tc.shouldContinue())
break;
}
}
}
에 대해 어떻게 :
당신의 Callable
ExecutorService
에 제출하고 반환 된 Future
에 대한 핸들을 유지한다.
ExecutorService executorService = ... // Create ExecutorService.
Callable<Result> callable = new MyCallable(); // Create work to be done.
Future<Result> fut = executorService.submit(callable);
랩을 Delayed
의 getDelay(TimeUnit)
방법은 해당 작업에 대한 최대 실행 시간을 반환함으로써 Delayed
의 구현에 Future
을.
public class DelayedImpl<T> implements Delayed {
private final long maxExecTimeMillis;
private final Future<T> future;
public DelayedImpl(long maxExecTimeMillis, Future<T> future) {
this.maxExecMillis = maxExecMillis;
this.future = future;
}
public TimeUnit getDelay(TimeUnit timeUnit) {
return timeUnit.convert(maxExecTimeMillis, TimeUnit.MILLISECONDS);
}
public Future<T> getFuture() {
return future;
}
}
DelayedImpl impl = new DelayedImpl(3000L, fut); // Max exec. time == 3000ms.
Add the `DelayedImpl` to a `DelayQueue`.
Queue<DelayedImpl> queue = new DelayQueue<DelayImpl>();
queue.add(impl);
는 큐에서 반복적으로
take()
스레드를 가지고 각
DelayedImpl
의
Future
이
isDone()
를 호출하여 완료 여부를 확인; 그렇지 않으면 작업을 취소하십시오.
new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted) {
DelayedImpl impl = queue.take(); // Perform blocking take.
if (!impl.getFuture().isDone()) {
impl.getFuture().cancel(true);
}
}
}
}).start();
이 방법의 가장 큰 장점은 자동으로 실행 시간의 작은 금액이 남은 작업을 반환 작업 및 지연 큐 당 다른 최대 실행 시간을 설정할 수 있다는 것입니다.
아담 스키 :
내가 지연된 인터페이스의 구현이 제대로 작동하기 위해서는 약간의 조정이 필요하다고 생각합니다. 오브젝트의 인스턴스 생성으로부터 경과 한 시간이 최대 유효 기간을 초과하면 'getDelay()'의 리턴 값은 음의 값을 리턴해야합니다. 이를 달성하기 위해서는 작업이 생성 된 (그리고 아마도 시작된) 시간을 저장해야합니다. 그런 다음 'getDelay()'가 호출 될 때마다 스레드의 최대 수명이 초과되었는지 여부를 계산합니다. 마찬가지로 :
class DelayedImpl<T> implements Delayed {
private Future<T> task;
private final long maxExecTimeMinutes = MAX_THREAD_LIFE_MINUTES;
private final long startInMillis = System.currentTimeMillis();
private DelayedImpl(Future<T> task) {
this.task = task;
}
public long getDelay(TimeUnit unit) {
return unit.convert((startInMillis + maxExecTimeMinutes*60*1000) - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
public int compareTo(Delayed o) {
Long thisDelay = getDelay(TimeUnit.MILLISECONDS);
Long thatDelay = o.getDelay(TimeUnit.MILLISECONDS);
return thisDelay.compareTo(thatDelay);
}
public Future<T> getTask() {
return task;
}
}
Future.get (Long timeout, TimeUnit unit)은 TimeoutException을 throw합니다. future.cancel (true)를 호출하는 예외에 대한 추정치입니다. – JeeBee
Future.get (long, TimeUnit)은 * 특정 * Future가 완료 될 때까지 지정된 시간 동안 차단됩니다. 그러나 내가 추가 한 솔루션을 사용하면 특정 스레드에서 * 차단 *이 아닌 진행중인 모든 Callable을 확인하는 단일 스레드를 가질 수 있습니다. 5 분이 걸릴 Callable을 제출한다고 가정합니다. 내 "수표"스레드에서 future.get (5L, TimeUnit.MINUTES)을 호출합니다. 다른 Callable은 10 초의 최대 실행 시간으로 제출됩니다. 그러나 스레드는 이전 차단 호출이 반환 될 때까지이 두 번째 Callable이 10 초 이상 실행되었는지 여부를 확인하지 않습니다. – Adamski