如何保护java中的方法(溢出等)



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

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

谢谢

首先,我应该指出停止线程并不容易。实际上,在一般情况下,不能安全地停止线程:

  • 你可以在你想要停止的线程上调用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块中完成。)

注意startMethodendMethod调用可以(也许应该)由注释处理器或类似的东西插入。


考虑到复杂性,以及您不能保证(安全)停止线程的事实,我认为一些不涉及方法看门狗的解决方案

对象的普通方法在某个线程上运行。它可能是AWT事件调度器或者它的名字。或者它可能是主线程,例如,控制台应用程序的主线程。

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

我猜你的看门狗需要查看虚拟机中的所有线程,并寻找具有利用率>=某些阈值的线程。

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

丰富

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

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

方法将在超时时被中断。

最新更新