使用 JNA 本机等待调用检测线程中断 (Windows)

Posted

技术标签:

【中文标题】使用 JNA 本机等待调用检测线程中断 (Windows)【英文标题】:Detecting thread interruption with JNA native wait call (Windows) 【发布时间】:2011-10-25 12:19:31 【问题描述】:

我正在尝试编写一些通过 JNA 执行等待的代码(例如,通过调用 Kernel32 函数 WaitForSingleObject),但如果调用 Thread.interrupt(),我也希望等待完成;我假设 Java 使用类似 Event 对象的东西来实现中断;有没有办法从 Java 获取事件以便在调用 WaitForMultipleObjects 时使用它?或者如果线程被中断,我还有其他方法可以安排我的等待完成吗?

【问题讨论】:

【参考方案1】:

Java 通过 NIO 支持它,但很少有人知道,有问题的类是抽象的,但这没问题:

java.nio.channels.spi.AbstractInterruptibleChannel。它有 3 种有趣的方法:begin()end(),它们是最终的,加上你必须实现的方法:“protected abstract void implCloseChannel() throws IOException” 该方法将从调用interrupt()的线程中调用,所以要小心。

使用很简单:在输入本机代码之前调用begin,返回时调用end()。处理 implCloseChannel 中的中断。

编码愉快!

【讨论】:

谢谢。这比我做的方式好多了。【参考方案2】:

今天早上我抽出一点时间做更多的研究,去挖掘 OpenJDK 源代码。事实证明,从原生实现开始是错误的;有一个纯 Java 机制可以做到这一点。

sun.misc.SharedSecrets 类有一个静态方法 getJavaLangAccess(),它返回一个带有方法 blockedOn(Thread, sun.nio.ch.Interruptible) 的对象。这可用于安排 Thread.interrupt() 调用由我自己的对象之一提供的方法,此时我可以创建自己的中断事件对象,我可以使用该对象确保根据需要终止等待。

这样做会引入对 sun 的 Java 类库实现的依赖,但可能不如挖掘 JVM 的本机状态以尝试提取它在内部使用的事件句柄。

【讨论】:

以上是关于使用 JNA 本机等待调用检测线程中断 (Windows)的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 JNA 找出本机类型的映射

使用 JNA 使用本机 fortran 库时查找 SIGSEGV 原因的问题

命名管道服务器,如何中断或超时等待客户端连接和传入数据

Java线程中断

中断线程

在 Windows 上使用 JNA 调用 __cpuid 函数