首页 文章

Java - 超时长时间运行可调用线程

提问于
浏览
1
public class FutureGetTimeoutTest {

    private static final ExecutorService THREAD_POOL = Executors.newFixedThreadPool(5);

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        List<String> respList = new ArrayList<String>();

        List<Future<String>> futures = new ArrayList<Future<String>>();
        futures.add(THREAD_POOL.submit(new CallableTask(1L)));
        futures.add(THREAD_POOL.submit(new CallableTask(2L)));
        futures.add(THREAD_POOL.submit(new CallableTask(3L)));

        long start = System.currentTimeMillis();
        System.out.println(start);
        for (Future<String> future : futures) {
            try {
                respList.add(future.get(10000, TimeUnit.MILLISECONDS));
                /*
                 * Timeout time for 2nd Task starts only at the end of 1st Task Timeout
                 * and so 2nd task is able to run for 20s and 3rd task for 30s!
                 */
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println(end);
        System.out.println(end - start);
        System.out.println(respList);

    }

}

class CallableTask implements Callable<String> {

    private long ipAddressL;

    public CallableTask(long ipAddressL) {
        this.ipAddressL = ipAddressL;
    }

    @Override
    public String call() throws Exception {

        if (ipAddressL == 1) {
            Thread.sleep(10000);
            /* Imagine a DB operation taking more time. */
            return "1";
        } else if (ipAddressL == 2) {
            Thread.sleep(20000);
            return "2";
        } else {
            Thread.sleep(30000);
            return "3";
        }

    }
}

我想返回一个空字符串或只是终止线程或从每个任务中抛出一个TimeoutException,如果 each 任务单独占用超过10秒 .

假设第一个线程需要10秒, Future.get() 将等待10秒然后超时 . 我将捕获异常并继续迭代第二个未来对象 . 说第二个线程此时没有完成(这意味着它在第一个线程运行并且仍在运行时运行了10秒),现在第二个线程上的 Future.get() 将等待另外10秒,因此总共20秒等等以后续线程 .

future.get(1000, TimeUnit.MILLISECONDS) (1 sec),

将确保整个操作的10s限制,但我需要对每个单独的并发任务设置10s限制整个操作 .

1 回答

  • 1

    使用 THREAD_POOL.invokeAll 而不是 submit 等待10秒才能完成任务 .

    如果某些任务在10秒之前完成,您可以使用 future.isDone() 进行检查,并使用 future.get 检索结果而不会阻塞 .

相关问题