当前位置: 首页 > 知识库问答 >
问题:

在没有主线程的情况下保持控制台输入活动?(Java)

高宸
2023-03-14

我正在用Java编写一个服务器,它是多线程的。我有三个主要的活动线程,我从我的main方法开始构建:

public class Run{
     public static void main(String[] args){
        try{
            /*
             *  Definition and initialization of "server," "time," and 
             *  "commands" variables not shown.
             */

            new Thread(server).start();
            new Thread(time).start();
            new Thread(commands).start();
        }catch(FileNotFoundException unfound){
            /* Exception code not shown */
        }catch(IOException ioe){
            /* Exception code not shown */
        }
     }
}

例如,我的命令线程用于通过将输入“q”放入控制台窗口来停止服务器。命令的运行方法定义如下:

public void run(){
    while(server.running.get()){
        try{
             String next = scan.nextLine();
             if(next.equalsIgnoreCase("q")){
                  server.shutdown();
                  close();
             }else
                  System.out.println(LocalDateTime.now() + " - Unknown command.");
        }catch(IOException ioe){
             System.out.println(LocalDateTime.now() + " - The commands thread has produced an exception.");
        }
    }
}

*其中扫描定义为:扫描仪扫描=新扫描仪(System.in);

当我运行服务器时,我的所有线程都工作,除了命令线程,因为控制台不接受输入。

然后我意识到,如果我等待我的服务器线程(这是我最关心的线程)与我的主(静态方法)线程连接,我的命令线程就会起作用。这意味着如果我将主方法代码更改为以下内容,控制台将接受输入:

Thread t1 = new Thread(server);
t1.start();
new Thread(time).start();
new Thread(commands).start();
try{
    t1.join();
}catch(Exception e){
    e.printStackTrace();   
}

现在回答我的问题。为什么控制台输入只有在主线程仍然活动的情况下才起作用?老实说,我不再需要我的主线程了,所以让它终止就可以了。

我是否做错了什么,只定义了没有名字的线程?我能够很好地终止每个线程,因为它们是相互交织的,除了我的命令线程之外,一切都正常。

编辑:我真的很感谢所有关于解决这个问题的答案,但我真正想要的是为什么会发生这种情况的原因。

服务器线程螺旋式下降并自行html" target="_blank">执行(即不断寻找新的连接并为这些连接建立新的环境),而续订线程也会下降并自行完成(即当我使用google API时,这用于更新我的配额计数)。除此之外,上面的代码还说明了我在做什么。

共有3个答案

燕智
2023-03-14

JVM负责主线程和IO流。您可以尝试通过在主线程中保存/隐藏其实际值来保持输入流不变(通常的测试方法):

InputStream consoleInput = System.in;
System.setIn(new ByteArrayInputStream(new byte[0]));
仲孙疏珂
2023-03-14

当main消失时,我看不出从另一个线程读取有任何问题:

public class IOWithoutMain {

  public static void main(String[] args) {
    RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
    System.out.printf("%s %s %s (%s)%n",
        runtime.getVmVendor(),
        runtime.getVmName(),
        System.getProperty("java.version"),
        runtime.getVmVersion());
    new Thread() {
      public void run() {
        try {
          sleep(10_000);
          System.out.print("Enter input: ");
          InputStreamReader isr = new InputStreamReader(System.in);
          BufferedReader br = new BufferedReader(isr);
          System.out.println(br.readLine());
        } catch (InterruptedException|IOException e) {
          e.printStackTrace();
        }
      }
    }.start();
  }
}

控制台:

Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 1.8.0_60 (25.60-b23)
Enter input: Test
Test
丌官瀚
2023-03-14

您应该让您的命令线程成为您的主线程。只需在其他一切启动后将其放在main()中:

commands.run();
 类似资料:
  • 问题内容: 我可以在python中获得没有回声的控制台输入吗? 问题答案: 使用getpass:

  • 问题内容: 示例问题: 实体: 用户包含姓名和朋友列表(用户参考) 博客文章包含标题,内容,日期和作者(用户) 需求: 我想要一个显示标题的页面以及指向用户朋友的最近10篇博客的链接。我还希望能够通过较旧的条目继续进行分页。 SQL解决方案: 因此在sql land中,它将类似于: 我能想到的GAE解决方案是: 加载用户,循环浏览好友列表并加载其最新博客帖子。最后合并所有博客文章以查找最新的10个

  • 为了在我的应用程序中执行一些IO操作,我编写了一个线程,它的run方法上没有任何东西,但它有几个其他方法,比如void write(字符串文件名,字符串数据)和void create(字符串文件号),所有这些方法都非常有效。我的问题是,我过去认为这个线程是在后台运行的,或者类似的东西,但是自从删除了主活动上的.run()语句后,调用所述方法仍然有效,我如何让一个线程运行并等待活动的消息而不阻塞应用

  • 我正在使用Spring框架和Hibernate开发一个web应用程序。我的问题是,我经常收到404错误,这是因为我在代码库的某个地方犯了一个错误,但控制台中没有异常消息。正因为如此,我很难找到错误在哪里,因为项目已经变得非常大,手动尝试找到问题是不切实际的。我假设是Spring导致了这个问题,所以我的问题是:是否有某种方法可以启用更详细的错误消息?谢谢

  • 问题内容: 我想将Java控制台输出(由Ilk和Ilk 生成)通过管道传输到文件。我在这里找到了一个出色的解决方案来启用Java跟踪,但这对我不起作用(在Mac OS X或Windows上的任何位置都没有显示日志文件)。据我所知,这是因为我使用的是没有Java Web Start的普通Java应用程序。那么如何使用不使用Java Web Start的Java代码来做到这一点呢?理想情况下,我想要一

  • 我对套接字和以这种方式使用线程相当陌生。 我遇到了一个问题,一个扫描器在等待用户输入,一个输入流阅读器在等待套接字通信。我的程序试图与客户机/服务器系统通信,这很好,但我也希望能够通过扫描仪或类似的东西直接将命令输入控制台。但是,主线程的while循环阻塞了套接字通信,而扫描器阻塞了InputThread的while循环。 我的问题是,如果我在控制台中发送命令关闭服务器(将布尔'running'设