执行Java函数的时间限制

时间:2012-04-28 00:06:36

标签: java multithreading

我正在尝试构造两个线程,线程A是主线程,线程B是第二个线程,线程B通过耗时的函数更新变量(这个变量应该在两个线程之间共享,因为最终线程A需要使用该变量),但是如果线程B花费太长时间来完成(使用异常),我希望线程A终止线程B.

我尝试的是以下内容:

Thread thread = new Thread() {
     public void run() {
         /// run something that could take a long time
     }
};

synchronized (thread) {
    thread.start();
}

System.err.println("Waiting for thread and terminating it if it did not stop.");
try {
   thread.wait(10000);
} catch (InterruptedException e) {
   System.err.println("interrupted.");
}

如果行为超过10秒,是否会产生终止行为的预期行为?在等待之后线程对象被删除,因为运行该线程的方法返回。

现在,这段代码发生的事情是我总是在wait(10000)命令上得到java.lang.IllegalMonitorStateException。

2 个答案:

答案 0 :(得分:3)

如果您在IllegalMonitorStateException上没有wait()的对象上致电synchronized,您将始终获得try { // you need this to do the wait synchronized (thread) { thread.wait(10000); } } catch (InterruptedException e) { System.err.println("interrupted."); }

thread

如果您正在等待try { thread.join(10000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("interrupted."); } 完成,那么您可能正在尝试:

join

不幸的是,你不知道线程是否正在运行,因为thread.isAlive()不会返回它是否超时(抱怨)。因此,您需要测试加入后是否thread

如果您问如何取消10000如果其运行时间超过thread.interrupt()毫秒,那么正确的做法就是使用sleep()。这将导致任何wait()InterruptedException方法抛出 while (!Thread.currentThread.isInterrupted()) { // do it's thread stuff } ,它将在线程上设置中断标志。

要使用中断标志,您的线程应该执行以下操作:

InterruptedException

此外,执行类似以下操作总是一个好的模式,因为一旦抛出} catch (InterruptedException e) { // set the interrupt flag again because InterruptedException clears it Thread.currentThread.interrupt(); System.err.println("interrupted."); } ,中断标志就被清除了:

{{1}}

答案 1 :(得分:1)

该代码不正确。方法waitObject类中声明,旨在使用作为调用它的对象的监视器实例来挂起当前线程。您可以仅在synchronized部分调用此方法,这就是您获得异常的原因。

关于你的问题:一般来说,如果不想停止,你就无法阻止另一个线程。因此,您应该调用Thread.interrupt来通知线程它应该停止工作,并由该线程决定是否考虑该通知。要检查线程是否被中断,您可以使用interrupted()isInterrupted()方法。