6

我必须用 Java 编写一个“看门狗”,以确保线程不会执行太长时间。初始化对象没问题,我创建了一个类,它调用 WatchDog 和带有 run() 方法中的反射的构造函数。

线程很容易停止,但我如何保护对象的正常方法?例如我调用一个对象的方法,这个方法执行一个无限循环,你会怎么做?

谢谢

4

3 回答 3

4

首先,我应该指出,停止线程并不容易。事实上,在一般情况下,线程是无法安全停止的:

  • 您可以调用Thread.interrupt()要停止的线程,但不能保证线程会注意到中断,更不用说实际停止了。

  • 您可以调用已弃用的Thread.stop()方法,但此方法不安全。如果你在一个不幸的时刻调用它,你可以让数据结构处于半更新状态,让其他线程(永远)等待不会到达的信号等等。


以下是我如何为方法执行实现看门狗。

首先,我将修改方法以向看门狗服务添加两个调用;例如

public void someMethod(...) {
    Watchdog.startMethod(maxTime);
    // do stuff
    Watchdog.endMethod();
}

接下来,我将使用按到期时间排序的优先级队列来实现看门狗:

  1. startMethod(maxTime)将向队列中添加一个条目,其到期时间为now + maxTime。该条目将包括对当前线程的引用(调用该方法时。
  2. endMethod()将为当前线程寻找(该)队列条目,如果找到则将其删除。
  3. 看门狗线程将定期查看第一个队列条目。如果该条目的到期时间小于“现在”,则看门狗将删除该条目,停止其线程并检查下一个条目。重复直到下一个条目没有过期。

需要对数据结构和处理endMethod跳过调用的情况进行一些思考。(事实上​​,由于一个方法调用可以因异常而终止,所以endMethod()调用确实需要在一个finally块中完成。)

请注意,startMethodandendMethod调用可以(并且可能应该)由注释处理器或类似的东西插入。


鉴于复杂性以及您不能保证(安全地)停止线程的事实,我会想到一些不涉及方法看门狗的解决方案。

于 2011-08-09T13:53:05.123 回答
3

对象的普通方法在某个线程上运行。它可能是 AWT 事件分派器或任何它被调用的东西。或者它可能是控制台应用程序的主线程。

它们与使用 new Thread() 调用的线程没有什么不同。

我猜你的看门狗需要查看 VM 中的所有线程并寻找利用率 >= 某个阈值的线程。

到目前为止你有什么代码?

富有的

于 2011-08-09T11:57:06.427 回答
1

尝试使用@Timeable来自jcabi-aspects 的注释:

public class Resource {
  @Timeable(limit = 5, unit = TimeUnit.SECONDS)
  public String load(URL url) {
    return url.openConnection().getContent();
  }
}

您的方法将在超时时中断。

于 2013-05-05T14:46:20.437 回答