如何在methodB超N秒未被调用时执行methodC及实现循环触发逻辑
实现methodB超时未调用时执行methodC的方案
核心思路是用定时调度器管理超时任务:每次调用methodB时,取消之前未触发的超时任务,重新调度一个N秒后执行methodC的任务;若methodB在N秒内未被调用,调度器就会触发methodC。
具体实现步骤
- 初始化
ScheduledExecutorService用于调度超时任务 - 用线程安全的方式维护
Future对象,跟踪当前待执行的超时任务 - 在
methodB中先取消现有未执行的超时任务,再重新调度新的超时任务 - 确保不再使用时关闭调度器,避免资源泄漏
修改后的代码示例
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; public class AudioProcessor { // 自定义超时时间N秒,按需调整 private static final int TIMEOUT_SECONDS = 5; private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); private volatile ScheduledFuture<?> timeoutFuture; public void methodB(byte[] audioData) throws IOException { // 取消之前未执行的超时任务 if (timeoutFuture != null && !timeoutFuture.isDone()) { timeoutFuture.cancel(false); } // 原有业务逻辑 byte[] transcodedVoice = transcodeVoice(audioData); recognizer.acceptWaveForm(transcodedVoice, transcodedVoice.length); // 重新调度:N秒后执行methodC timeoutFuture = scheduler.schedule(this::methodC, TIMEOUT_SECONDS, TimeUnit.SECONDS); } public void methodC() { // 业务逻辑实现 System.out.println("Method B stops getting data"); } // 关闭调度器,释放资源 public void cleanup() { scheduler.shutdown(); try { if (!scheduler.awaitTermination(1, TimeUnit.SECONDS)) { scheduler.shutdownNow(); } } catch (InterruptedException e) { scheduler.shutdownNow(); } } // 以下为原有方法占位,根据实际业务补充实现 private byte[] transcodeVoice(byte[] audioData) { // 音频转码逻辑 return audioData; } private Recognizer recognizer = new Recognizer(); private static class Recognizer { public void acceptWaveForm(byte[] data, int length) { // 语音识别逻辑 } } }
关键细节说明
- 线程安全:用
volatile修饰timeoutFuture,保证多线程环境下的变量可见性;cancel(false)仅取消未执行的任务,不会中断正在运行的线程 - 重复检测:每次调用methodB都会重置超时任务,自动实现“再次收到数据后重复检测”的需求
- 资源泄漏防范:必须调用
cleanup()关闭调度器,避免后台线程长期占用资源
内容的提问来源于stack exchange,提问作者grnelph
相关产品推荐
相关产品推荐

