我正在用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时,这用于更新我的配额计数)。除此之外,上面的代码还说明了我在做什么。
JVM负责主线程和IO流。您可以尝试通过在主线程中保存/隐藏其实际值来保持输入流不变(通常的测试方法):
InputStream consoleInput = System.in;
System.setIn(new ByteArrayInputStream(new byte[0]));
当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
您应该让您的命令线程成为您的主线程。只需在其他一切启动后将其放在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'设