使用J32调用Win32 WaitForSingleObject()时Java计时器不运行

时间:2011-12-22 19:34:27

标签: java jna

我正在尝试使用WaitForSignleObject()终止对Timer的JNA调用,该调用会中断当前线程:

final Thread thread = Thread.currentThread();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
  public void run() {
    thread.interrupt();
  }
}, 3000);

try {               
  Kernel32.INSTANCE.WaitForSingleObject(processInfo.hProcess, Kernel32.INFINITE);
  ...
} catch (InterruptedException e) {
}

问题是TimerTask.run()在按预期过了3秒后才被调用,只有在WaitForSingleObject()退出后才会调用它。我做错了什么?

谢谢!

4 个答案:

答案 0 :(得分:2)

线程中断机制是一种特定于Java的功能,因此本机代码不尊重它就不足为奇了。

如果您只需要超时,则可以使用WaitForSingleObject()的第二个参数。如果您需要更复杂的逻辑,可以create an event通知等待线程中断,并对该事件使用WaitForMultipleObjects()hProcess

答案 1 :(得分:1)

这个简单的代码有很多错误;

  • run()代码中断当前调用线程 - 没用,你希望线程进行本机调用。
  • 您需要处理原生呼叫本身的中断。

下面链接到如何从java端正确处理。 Detecting thread interruption with JNA native wait call (Windows)

在WinAPI端:根据您的情况,您可能需要CloseHandle,SetEvent或您需要的任何通知。 然后从WaitForSingleObject返回后检查对象状态并在必要时抛出InterruptedException。

答案 2 :(得分:0)

在查看Microsoft的WaitForSingleObject文档时,有人建议您可以考虑使用WaitForSingleObjectEx(为了进入“可警告的等待状态”)。

答案 3 :(得分:0)

  

问题是TimerTask.run()在3秒后没有被调用   按预期传递,只有在WaitForSingleObject()退出后调用它   本身。我做错了什么?

简单的答案:您正在对操作系统进行阻止调用。当你的线程被阻塞时,该线程中的TimerTask将不会被触发。

即使你在另一个线程上运行TimerTask,中断也不太可能,因为Thread.interrupt是Java特有的功能(正如@axtavt所指出的那样)。

如果您想获得更多帮助,请创建另一个帖子并解释您为什么需要这样做以及您的约束条件(更具体的内容比“......它会破坏我的API”)。也许我们会找到另一种方法。