我必须在Java中编写一个“WatchDog”,它确保Threads的执行时间不会太长。随着对象的初始化没有问题,我创建了一个类,它使用run()方法中的反射来调用WatchDog和构造函数。
线程很容易停止,但我如何才能保证对象的常规方法? 例如,我调用Object的方法,这个方法执行无限循环,你会怎么做?
谢谢
答案 0 :(得分:4)
首先,我应该指出停止线程不很容易。事实上,在一般情况下,线程无法安全停止:
您可以在要停止的线程上调用Thread.interrupt()
,但无法保证线程会注意到中断,更不用说实际停止了。
您可以调用已弃用的Thread.stop()
方法,但此方法不安全。如果你在一个不幸的时刻调用它,你可以让数据结构处于半更新状态,让其他线程等待(永远)等待无法到达的信号,等等。
以下是我为方法执行实现监视程序的方法。
首先我修改方法,向看门狗服务添加两个调用;例如
public void someMethod(...) {
Watchdog.startMethod(maxTime);
// do stuff
Watchdog.endMethod();
}
接下来,我将使用在到期时间排序的优先级队列实现Watchdog:
startMethod(maxTime)
会在队列中添加一个条目,其到期时间为now + maxTime
。该条目将包括对当前线程的引用(当调用该方法时。endMethod()
将查找当前线程的(队列)条目,如果找到则将其删除。需要考虑数据结构,并处理跳过endMethod
调用的情况。 (实际上,由于方法调用可能因异常而终止,因此endMethod()
调用确实需要在finally
块中完成。)
请注意,startMethod
和endMethod
调用可以(也可能应该)由注释处理器或类似内容插入。
鉴于复杂性以及您无法保证(安全地)停止线程的事实,我会想到一些不涉及方法监视器的解决方案。
答案 1 :(得分:3)
对象的常规方法正在某些线程上运行。它可能是AWT事件调度程序或其所谓的任何调度程序。或者它可能是控制台应用程序的主要线程。
它们与使用新Thread()调用的线程没有区别。
我想你的看门狗需要查看虚拟机中的所有线程,并寻找利用率> =某个阈值的线程。
到目前为止,你有什么代码?
富
答案 2 :(得分:1)
尝试使用@Timeable
中的jcabi-aspects注释:
public class Resource {
@Timeable(limit = 5, unit = TimeUnit.SECONDS)
public String load(URL url) {
return url.openConnection().getContent();
}
}
您的方法将在超时时中断。