Java 在线程中运行消息循环

Java 在线程中运行消息循环,java,jna,Java,Jna,我想使用JNA运行一个低级键盘钩子。我改编了JNA contrib文件夹中的一个示例 private static HHOOK keyHook; private static LowLevelKeyboardProc keyCallback; public static void main(String[] args) { final User32 U32 = User32.INSTANCE; final Kernel32 K32 = Kernel32.INSTANCE;

我想使用JNA运行一个低级键盘钩子。我改编了JNA contrib文件夹中的一个示例

private static HHOOK keyHook;
private static LowLevelKeyboardProc keyCallback;

public static void main(String[] args) {
   final User32 U32 = User32.INSTANCE;
   final Kernel32 K32 = Kernel32.INSTANCE;

   HMODULE module = K32.GetModuleHandle(null); 
   keyCallback = (int code, WPARAM wParam, KBDLLHOOKSTRUCT info) -> {
      if (code >= 0) {
         System.err.println("Key=" + info.vkCode);
         if (info.vkCode == 81) {
           U32.PostQuitMessage(0);
         }
      }
      long peer = Pointer.nativeValue(info.getPointer());
      return U32.CallNextHookEx(keyHook, code, wParam, new LPARAM(peer));
   };
   keyHook = U32.SetWindowsHookEx(WH_KEYBOARD_LL, keyCallback, module, 0);
   System.out.println("Hook installed, type anywhere, 'q' to quit");

   MSG msg = new MSG();
   while (U32.GetMessage(msg, null, 0, 0) > 0) {         
      U32.TranslateMessage(msg);
      U32.DispatchMessage(msg);               
   }
   U32.UnhookWindowsHookEx(keyHook);
}
这是预期的工作。不过,现在我想在线程中运行消息循环,以避免阻塞我的应用程序。一个天真的方法是

Executor thread = Executors.newSingleThreadExecutor();
thread.execute(() -> {
   int result;
   MSG msg = new MSG();
   while ((result = U32.GetMessage(msg, null, 0, 0)) > 0) {         
      U32.TranslateMessage(msg);
      U32.DispatchMessage(msg);               
   }
   U32.UnhookWindowsHookEx(keyHook);
});
遗憾的是,这不起作用。回调不再被调用,系统上的键盘输入开始大量滞后。如何正确地执行消息循环线程?我想我需要找到线程id并将其传递给
SetWindowsHookEx
,而不是0,但是如何获得该id呢


编辑:我尝试了一种不同的方法,将整个钩子注册和消息循环封装在一个线程中。回调现在可以正常工作,但
PostQuitMessage
似乎无法将消息发布到正确的队列,线程无法停止<代码>PostThreadMessage(0,User32.WM_退出,null,null)在这种情况下也不起作用。

我发现解决方案实际上已经由JNA平台提供了,我手头没有JNA框架,但是从不同的线程调用
SetWindowsHookEx
方法,而不是执行钩子的线程听起来很粗略。尝试运行
线程内的所有回调代码。执行
部分。用此更新问题。这明显更好,但现在PostQuitMessage不起作用。