首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ThreadPoolExecutor超时配置

ThreadPoolExecutor超时配置
EN

Stack Overflow用户
提问于 2015-06-18 17:26:33
回答 1查看 3.7K关注 0票数 0

我想为我的ThreadPoolExecutor设置一个超时。

我知道我可以用

代码语言:javascript
复制
future.get(THREAD_TIMEOUT_MS, TimeUnit.MILLISECONDS);

但是这段代码是阻塞的。

我想要实现的是,我可以创建几个Runables,这些Runables是由4个线程池处理的。

如果线程的处理时间超过5秒,我想抛出一个超时异常。

这是我当前的设置:

代码语言:javascript
复制
public class ServerExecutorService {

    public static int QUEUE_KEEP_ALIVE_TIME_SECONDS = 5;
    public static int MAXIMUM_POOL_SIZE = 12;
    public static int CORE_POOL_SIZE = 12;
    public static Logger LOG = LoggerFactory.getLogger(ServerExecutorService .class);
    public static int THREAD_TIMEOUT_MS = 5000;
    private LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue(2);
    private RejectedHandler rejectedHandler = new RejectedHandler();


    private ThreadPoolExecutor executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, QUEUE_KEEP_ALIVE_TIME_SECONDS, TimeUnit.SECONDS, linkedBlockingQueue);

    public ServerExecutorService () {
        executor.setRejectedExecutionHandler(this.rejectedHandler);
    }

    public void setRejectedHandler(RejectedHandler rejectedHandler) {
        executor.setRejectedExecutionHandler(rejectedHandler);
    }


    public void execute(Runnable runnable){
//        executor.execute(runnable);
//        Future<?> future = executor.submit(runnable);
        Future<?> future = executor.submit(runnable);

        try {
            future.get(THREAD_TIMEOUT_MS, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            System.out.println("Thread processing timeout.");
            LOG.warn("Thread processing timeout.", e);
        } catch (Exception e) {
            System.out.println("Thread processing error within ServerExecutorService ");
            LOG.error("Thread processing error within ServerExecutorService ", e);
        }
    }

}

但是,就像您看到的future.get(THREAD_TIMEOUT_MS,TimeUnit.MILLISECONDS);将等待线程完成。因此,下一个线程不会启动。

测试:

代码语言:javascript
复制
@Test
    public void testThreadPoolExhausted() {
        serverExecutorService.setRejectedHandler(rejectedHandler);
        for (int i = 0; i < 4; i++) {
            final int finalI = i;
            serverExecutorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("do something" + finalI);
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

在此测试中,第二个线程在3秒后启动,而不是立即启动。

EN

回答 1

Stack Overflow用户

发布于 2015-06-18 17:55:51

您可以创建两个线程池,一个用于超时,另一个用于实际工作。

代码语言:javascript
复制
ExecutorService timeoutService = Executors.newCachedThreadPool();
ExecutorService workerService = Executors.newCachedThreadPool();

public Future<?> submit(final Runnable runnable){
    return timeoutService.submit(() -> {
        try {
            Future<?> future = workerService.submit(runnable);
            future.get(100, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30911479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档