简体   繁体   English

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

[英]Concurrent/Non-blocking console keyboard input

I'm working on a MUD in java. 我正在研究java中的MUD。 I read player input every tick, but I'm using Scanner which uses blocking operations. 我每次打勾都会读取播放器输入,但我正在使用使用阻塞操作的Scanner 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 . 我查看了具有Selector类的nio包,但我不确定如何在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. 我已经尝试从Applet扩展主类并覆盖keyDown ,但这只是意味着在第一个之后不再接受输入。 Sure, I wasn't blocking anything anymore, but then there was no more input. 当然,我不再阻止任何东西了,但是没有更多的输入。 keyDown never got called again, I guess. 我想, keyDown再也没有被调用过。

Perhaps threads can be interrupted even when they are executing blocking operations? 也许线程即使在执行阻塞操作时也可能被中断?

Thanks for any insight into this problem. 感谢您对此问题的任何见解。

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. 您可以使用swing窗口作为控制台或查找基于JNI的方法,但它可能无法在某些平台上运行。

You may use JCurses . 你可以使用JCurses It might work, it's based on JNI and supports Windows and Linux. 它可能有用,它基于JNI并支持Windows和Linux。

keyDown() is deprecated so I'd suggest to use processKeyEvent and a keyListener instead. 不推荐使用 keyDown(),所以我建议使用processKeyEventkeyListener

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. 是,如果您有对要中断的线程对象的引用,则只需在该实例上调用interrupt()方法即可。 And in the run method of the thread you can handle the interrupted exception. 在线程的run方法中,您可以处理中断的异常。 However, this seems a little bit hack-ish. 然而,这似乎有点黑客攻击。 I don't see how this is more helpful than using a simple KeyListener. 我没有看到这比使用简单的KeyListener更有帮助。

I had had to solve similar problem with blocking writing/reading from http. 我不得不解决阻止从http写入/读取的类似问题。 In that particular case I used local buffer and Threads. 在那种特殊情况下,我使用了本地缓冲区和线程。

Idea is simple, one Thread read from stdin and put content in buffer. 想法很简单,一个线程从stdin读取并将内容放入缓冲区。 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 ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM