处理线程最长执行时间的最佳方法(在Java中)

wil*_*eer 7 java concurrency multithreading

所以,我很好奇.如何处理为线程设置最长执行时间?在线程池中运行时?

我有几种技巧,但我对它们并不十分满意.所以,我想我会问社区他们是怎么做的.

Ada*_*ski 5

怎么样:

提交你的Callable,ExecutorService并保留回复的句柄Future.

ExecutorService executorService = ... // Create ExecutorService.
Callable<Result> callable = new MyCallable(); // Create work to be done.
Future<Result> fut = executorService.submit(callable);
Run Code Online (Sandbox Code Playgroud)

包含Future一个实现,Delayed其中DelayedgetDelay(TimeUnit)方法返回相关工作的最大执行时间.

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);
Run Code Online (Sandbox Code Playgroud)

有一个线程多次take()从队列中,并检查是否每个DelayedImplFuture是通过调用完成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();
Run Code Online (Sandbox Code Playgroud)

此方法的主要优点是您可以为每个任务设置不同的最大执行时间,延迟队列将自动返回剩余执行时间最短的任务.


Mar*_*ech 4

通常,我只是定期从线程代码中轮询控制对象。就像是:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)