4

我的主进程调用了一个外部库方法。此方法有时会挂起。我无法修复外部库,因为另一家公司负责它。

我想使用一个线程来调用具有定义的执行计时器的库。当方法调用需要很长时间时,放置方法调用的具有 Runnable 的线程应该停止,主进程应该继续前进。

  1. 主线程等待
  2. 执行线程
    • start 启动定时器线程
    • 当计时器线程完成时,杀死执行线程
  3. 执行线程停止主
  4. 线程恢复

有人有这个逻辑的代码,我可以使用的设计模式或我可以阅读一些信息的互联网页面吗?

谢谢

4

3 回答 3

2

这将等待线程完成最多 30 秒。

Thread t = new Thread() {
  public void run() {
    badExternalMethod();
    synchronized (this) {
      notifyAll();
    }
  }
};

synchronized (t) {
  t.start();
  try {
    t.wait(30000); // 30 secs
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
}

// t 已完成或超时

于 2009-05-07T10:42:32.123 回答
2

查看java.lang.concurrentJava 5 及更高版本中的包,特别是CompletionService接口和实现它的类。

此接口包括允许您提交任务并等待它完成或在超时后继续的调用。

于 2009-05-11T11:04:10.583 回答
1

您将无法神奇地使正在运行的线程在 30 秒后停止;您需要做的是让该线程在时间结束后检查某些状态,注意它花费的时间太长并且return来自其运行方法。

大致有两种方法可以做到这一点:

  1. 让库调用线程在每个花费少量时间的“块”中执行其操作,并检查每个块之间的状态。例如,如果您正在处理数十万条记录,您可能会在一批中处理数百条记录,然后检查标志。或者,如果您正在使用超时可用的潜在阻塞调用,请将超时设置为 500 毫秒并检查每次调用之间的标志。
  2. 让主线程在时间到时中断库调用线程,并确保库线程正确处理中断并在这种情况下检查标志。这将要求库调用线程执行可中断的方法,尽管任何可能长时间运行的方法都应允许中断。

在这两种情况下,您都需要让其中一个线程(可能是主线程,因为它无事可做)将“停止”标志设置为true一旦时间到了(并且这个变量应该被声明为 volatile 所以更新是所有线程都看到)。同样,当库调用线程看到这个标志为真时,它应该停止它正在做的事情,通常通过从 run() 方法返回。

您不应该真正从主线程中杀死库线程;请参阅Why are Thread.stop, Thread.suspend and Thread.resume Deprecated的原因,以及看起来与我上面描述的非常相似的替代方案。:-)

于 2009-05-07T10:52:28.527 回答