并发/非阻塞控制台键盘输入

发布于 2024-08-20 19:22:17 字数 383 浏览 7 评论 0原文

我正在用java开发MUD。我每次都会读取玩家输入,但我使用的是使用阻塞操作的 Scanner 。我想要非阻塞输入。

我查看了 nio 包,其中有一个 Selector 类,但我不确定如何在 System.in 中使用它>。我想一旦我运行服务器我肯定会需要它,但现在一切都处于离线状态。

我尝试从 Applet 扩展主类并覆盖 keyDown ,但这意味着在第一个输入之后不再接受输入。当然,我不再阻止任何东西,但随后就没有更多的输入了。我猜 keyDown 再也没有被调用过。

也许线程即使在执行阻塞操作时也可以被中断?

感谢您对这个问题的任何见解。

I'm working on a MUD in java. I read player input every tick, but I'm using Scanner which uses blocking operations. I want to have non-blocking input.

I've looked at the nio package which has a Selector class, but I'm not sure how to use it with regard to System.in. I figure I'll definitely need it once I'm running a server, but for now everything is offline.

I've tried extending the main class from Applet and overriding keyDown, but that just meant input was no longer accepted after the first one. Sure, I wasn't blocking anything anymore, but then there was no more input. keyDown never got called again, I guess.

Perhaps threads can be interrupted even when they are executing blocking operations?

Thanks for any insight into this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不离久伴 2024-08-27 19:22:17

您无法使用系统控制台执行此操作,因为目前还无法以多平台方式完成此操作。

您可以使用 Swing 窗口作为控制台或找到基于 JNI 的方法,但它可能不适用于某些平台。

您可以使用JCurses。它可能有效,它基于 JNI,支持 Windows 和 Linux。

You can't do that with the system console because by now it can't be done in a multi-platform way.

You can use swing window as console or find a JNI based approach but it might not work on some platforms.

You may use JCurses. It might work, it's based on JNI and supports Windows and Linux.

最美不过初阳 2024-08-27 19:22:17

keyDown() 是 已弃用 所以我建议使用 processKeyEventkeyListener 代替。

也许线程即使在执行阻塞操作时也可以被中断?

是的,如果您有要中断的线程对象的引用,您可以简单地调用 interrupt() 该实例上的方法。并且在线程的run方法中可以处理中断异常。然而,这似乎有点 hack 式。我不明白这比使用简单的 KeyListener 有什么帮助。

keyDown() is deprecated so I'd suggest to use processKeyEvent and a keyListener instead.

Perhaps threads can be interrupted even when they are executing blocking operations?

Yes if you have a reference to the thread object you want to interrupt, you can simply call interrupt() method on that instance. And in the run method of the thread you can handle the interrupted exception. However, this seems a little bit hack-ish. I don't see how this is more helpful than using a simple KeyListener.

灼疼热情 2024-08-27 19:22:17

我不得不解决类似的问题,阻止从 http 写入/读取。在这种特殊情况下,我使用了本地缓冲区和线程。

想法很简单,一个线程从标准输入读取内容并将内容放入缓冲区。其次,写作也同样如此。

然后您可以在缓冲区中使用非阻塞查询。

示例代码:

class NonBlockingReader implements Runnable{
  Reader in;
  List buffer;
  public void run(){
    String line=null;
    while((line=in.readLine())!=null){
      storeLine(line);
    }
  }
  private synchronized storeLine(String line){
    buffer.add(line);
  }
  public synchronized String getLine(){
    if(list.size()>0)
       return list.removeFirst();
    return null;
  }
}

// .. same for writer, then you jast pass stdin and stdout ...

I had had to solve similar problem with blocking writing/reading from http. In that particular case I used local buffer and Threads.

Idea is simple, one Thread read from stdin and put content in buffer. Second do same with writing.

And then you use nonblocking queries into your buffer.

Sample code:

class NonBlockingReader implements Runnable{
  Reader in;
  List buffer;
  public void run(){
    String line=null;
    while((line=in.readLine())!=null){
      storeLine(line);
    }
  }
  private synchronized storeLine(String line){
    buffer.add(line);
  }
  public synchronized String getLine(){
    if(list.size()>0)
       return list.removeFirst();
    return null;
  }
}

// .. same for writer, then you jast pass stdin and stdout ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文