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

时间:2009-08-05 16:48:01

标签: java concurrency multithreading

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

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

3 个答案:

答案 0 :(得分:5)

怎么样:

将您的Callable提交至ExecutorService,并处理返回的Future

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

Future包含在Delayed的实现中,其中Delayed的{​​{1}}方法返回相关作品的最长执行时间。

getDelay(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); ,并通过调用take()检查每个DelayedImpl的{​​{1}}是否完整;如果没有,则取消该任务。

Future

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

答案 1 :(得分:4)

Adamski的:

我认为您的延迟接口实现需要进行一些调整才能正常工作。如果从对象实例化开始所经过的时间量超过最大生命周期,则'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;
    }
}

答案 2 :(得分:3)

通常,我只是从线程代码中定期轮询一个控制对象。类似的东西:

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;
        }
    }
}