我们在开发的时候,常常会有这样的需要,需要保证某个操作只运行一段时间,如果超时了,就执行对应的超时操作。
比如,在读取网络请求的时候,我们希望3秒内能读到数据,如果超过了3秒没有读到,那么就不读了,提示用户,超时了,需要重试。
比如,我们开启了一个进程来执行一条命令,这个命令可能是批量处理一批文件并生成一个报告,或者其它,我们知道这个命令肯定不会执行超过30分钟,那么,我们需要给它设定一个时间,如果超时了,那么我们就杀掉该进程, 并清除掉错误的生成数据。
比如,我们通过USB接口将设备如电纸书,MP4等连接到电脑,如果尝试连接了一段时间而没有连接上,那么会给出指导,让用户检查设备或者进行重试。
诸如此类,还有很多。
对于第一种情况,我们还有选择,例如,我们可以通过设置socket的timeout时间来达到这个目的,但是对于大多数情况,它们都没有给我们太多这样原生的方式进行选择。
但是,对于这样的需求,apache-common-exec包中的WatchDog还是给了我们一个很好的例子。
这是一个简单的监听者模式的实现,WatchDog是Subject,TimeoutObserver自然就是Observer,从上图可以看出,WatchDog有着经典Subject的3个职责:
1. 管理Observer的职责,如addTimeoutObserver(),removeTimeoutObserver()方法
2. 触发Observer的职责,如fireTimeoutOccured()
3. 自己本身的业务逻辑,在run()方法中。
从类图上看,可以看出WatchDog类实现了Runnable接口,它在运行时实际上是一个deamon线程,看它的start()方法的实现:
public synchronized void start() {
stopped = false;
Thread t = new Thread(this, "WATCHDOG");
t.setDaemon(true);
t.start();
}
而它自己本身的业务逻辑则很简单,就是判断什么时候超时然后触发TimeoutObserver的timeoutOccured(w : Watchdog) : void 方法:
public synchronized void run() {
final long until = System.currentTimeMillis() + timeout;
long now;
while (!stopped && until > (now = System.currentTimeMillis())) {
try {
wait(until - now);
} catch (InterruptedException e) {
}
}
if (!stopped) {
fireTimeoutOccured(); //trigger TimeoutObserver#timeoutOccred() operation
}
}
protected final void fireTimeoutOccured() {
Enumeration e = observers.elements();
while (e.hasMoreElements()) {
((TimeoutObserver) e.nextElement()).timeoutOccured(this);
}
}
代码很简单,是不是?当我们有超时了需要进行某种操作的需求时,只需要将你需要进行的操作放到实现了TimeoutObserver接口的类中,比如:
public class NotifyUserTimeout implements TimeoutObserver {
@Override
public void timeoutOccured(Watchdog w) {
System.out.println("Timeout happens.. exit the applicaton now");
System.exit(-1);
}
}
然后调用WatchDog类进行超时时间的设置以及注册实现的TimeoutObserver即可。
static main(args) {
Watchdog watchDog=new Watchdog(3000);//set timeout for 3 seconds
watchDog.addTimeoutObserver new NotifyUserTimeout()
watchDog.start();
//simulate time-consuming task..
Thread.sleep 5000
println "finish normally.."
}
从上可以看到,我们模拟了正常的操作大概需要5秒,但是设置了超时的时限为3秒,当正常的操作超时后,会进行提示用户并且退出,上面的例子的结果输出为:
Timeout happens.. exit the applicaton now
看吧,两个简单的类,一个经典的设计模式,便很好的诠释了超时了该怎么办这个需求。如果你有这样的需求,不妨去试一试。
- 大小: 5.8 KB
分享到:
相关推荐
错误描述:oracle远程连接服务器出现 ORA-12170 TNS:连接超时 错误检查:有很多是oracle自身安装的问题,但是我这里服务器配置正常,监听正常,服务正常,远程可以ping通服务器。 这里主要是防火墙问题,解决办法: ...
行业分类-设备装置-读写超时的处理方法、装置及计算机可读存储介质.zip
网络游戏-在网络中确定超时延迟的方法.zip
行业分类-设备装置-电视应用测试中超时时间动态设置方法和装置.zip
电信设备-传输具有发射机超时的数据包信息的方法.zip
电子政务-中性点电阻柜超时运行自动切除保护装置及方法.zip
matlab开发-差分共跳超时变瑞利频分信道。时变瑞利衰落信道中的差分双跳中继
c代码-本例程展示了超时判断的原理
本文适用于本地的客户端连不上服务器的情况,并且对于怎样实现内网和外网的同时访问有一定的参考。
android串口调用,使用c开发的,可以设置串口超时。比谷歌的串口demo好(谷歌的IO堵塞模式),也可以使用堵塞时读取不超时。
QQ登陆超时怎么办?.docx
无线上网计时器,电信3G无线上网是包月包时的,这个软件可以让你知道自己到底上了多少时间,以免超时多交钱。
行业资料-交通装置-一种停车超时自动熄火器.zip
OpenFeign 使用两个超时参数:connectTimeout 连接超时 和 readTimeout 请求处理超时。以服务A 调用 服务B为例:连接超时时间 (connect-timeout):是指服务A去请求服务B的网络连接时间。读取超时时间/请求处理超时...
RA 相应窗口时间设置过小,导致 UE 检测窗口过短,不能在窗口内接收到 eNB 下发的 MSG2 消息。导致随机接入流程失败。对于窗口响应时间的大小,同终端接入 TA 大小相关, ...间,容易导致随机接入出现超时。
java超时取消正则表达式匹配方法,代码超时处理,设置代码执行时间,超棒的工具类 lambda,Callable,ExecutorService,超过执行5秒退出