1.背景
在多线程中定时调用Frame 获取音视频 当没有设备或资源过低时容易卡死阻塞了线程,后面的定时任务无法执行
2.处理
使用jdk内置的
Future
来定时结束卡死的业务
/**
* uptate_color(MhCameraGz mhCameraGz) 为自定义的业务
*/
@Async //多线程注释
public void uptate_color(MhCameraGz mhCameraGz) {
ExecutorService pool = Executors.newWorkStealingPool();
Future<String> future = pool.submit(() -> {
//业务内容
Frame frame = null;
FFmpegFrameGrabber grabber = null;
String file = "rtsp://xxxx:xxxxxxx@192.168.1.66:554/Streaming/Channels/1";
grabber = FFmpegFrameGrabber.createDefault(file);
grabber.setOption("rtsp_transport", "tcp");
grabber.setImageWidth(2688);
grabber.setImageHeight(1520);
grabber.start();
frame = grabber.grabImage();
//....
//业务内容end
return "aaa";
});
try {
//5秒内不执行完就跳出")
future.get(5, TimeUnit.SECONDS);
} catch (Exception e) {
future.cancel(true);
System.out.println("跳出");
}
return;
}
3.示例
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService pool = Executors.newWorkStealingPool();
Future<String> future = pool.submit(() -> {
System.out.println("开始执行");
//容易超时代码块
TimeUnit.SECONDS.sleep(8);
//容易超时代码块 end
System.out.println("执行完毕");
return "";
});
try {
future.get(6, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
System.out.println("执行超时超时了");
future.cancel(true);
}
//结束超时线程
System.out.println("结束");
return;
}