面试题答案
一键面试DelayedQueue
的使用场景
- 订单超时处理:在电商系统中,用户下单后,如果在规定时间(如30分钟)内未支付,订单将被取消并释放库存。可以将订单信息封装成实现
Delayed
接口的对象,放入DelayedQueue
。队列会按照设定的延迟时间来处理这些订单,实现自动取消功能。 - 缓存过期清理:在缓存系统中,当缓存数据设置了过期时间,使用
DelayedQueue
可以在数据过期时,自动将其从缓存中移除。把缓存数据项包装成Delayed
对象,放入队列,到期后进行清理操作。 - 定时任务调度:比如定期备份数据库的任务。将备份任务封装成
Delayed
对象,设定好延迟时间,放入DelayedQueue
,队列会在合适时间触发任务执行。
结合线程池处理延迟任务
- 创建线程池:
这里使用ExecutorService executorService = Executors.newSingleThreadExecutor();
Executors.newSingleThreadExecutor()
创建了一个单线程的线程池,也可以根据实际需求使用ThreadPoolExecutor
自定义线程池的参数,如核心线程数、最大线程数等。 - 创建延迟队列:
DelayedQueue<MyDelayedTask> delayedQueue = new DelayedQueue<>();
MyDelayedTask
是实现了Delayed
接口的自定义任务类。 - 向延迟队列添加任务:
这里创建了一个延迟5秒执行的任务并添加到队列中。MyDelayedTask task = new MyDelayedTask(5, TimeUnit.SECONDS); delayedQueue.add(task);
- 从队列中取出任务并交给线程池执行:
在线程池中开启一个循环,通过executorService.submit(() -> { while (true) { try { MyDelayedTask delayedTask = delayedQueue.take(); // 执行任务 delayedTask.run(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } });
delayedQueue.take()
方法从队列中取出延迟到期的任务并执行。如果线程在等待任务时被中断,会捕获InterruptedException
并终止循环,同时恢复线程的中断状态。
在实际应用中,还需要考虑异常处理、任务执行结果处理等更多细节,以确保系统的健壮性和可靠性。