如何在 Java 中永远运行程序?System.in.read() 是唯一的方法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12199011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to run a program forever in Java? Is System.in.read() the only way?
提问by ikevin8me
I took this code:
我拿了这个代码:
28 public static void main(String[] args) throws IOException {
29 HttpServer httpServer = startServer();
30 System.out.println(String.format("Jersey app started with WADL available at "
31 + "%sapplication.wadl\nTry out %shelloworld\nHit enter to stop it...",
32 BASE_URI, BASE_URI));
33 System.in.read();
34 httpServer.stop();
35 }
Does line 33 "System.in.read()" means that it will block until there is input? Will this also work when starting the Java application using UNIX rc script - not manually started from a command line?
第 33 行“System.in.read()”是否意味着它会阻塞直到有输入?这在使用 UNIX rc 脚本启动 Java 应用程序时也能工作 - 不是从命令行手动启动吗?
I'd like to write a Java application to listen for HTTP connections. The application will be started automatically when the system boots (using UNIX rc scripts). It means that the application will run continuously - theoretically forever, until purposefully stopped. What is the best way to implement this in the Java main() method?
我想编写一个 Java 应用程序来监听 HTTP 连接。该应用程序将在系统启动时自动启动(使用 UNIX rc 脚本)。这意味着应用程序将持续运行 - 理论上永远,直到有目的地停止。在 Java main() 方法中实现它的最佳方法是什么?
回答by Stepan Vavra
It looks like a weird black magic but following does the trick in very elegant way
它看起来像一个奇怪的黑魔法,但下面的方法非常优雅
Thread.currentThread().join();
As a result the current thread, main
for instance, waits on join()
for thread main
, that is itself, to end. Deadlocked.
结果,main
例如,当前线程等待join()
thread main
,即它本身,结束。陷入僵局。
The blocked thread must not be a daemon thread of course.
被阻塞的线程当然不能是守护线程。
回答by Joachim Sauer
Leaving the main
method in Java does notautomatically end the program.
将main
方法留在 Java 中不会自动结束程序。
The JVM exists if no more non-daemon threads are running. By default the only non-daemon thread is the main thread and it ends when you leave the main
method, therefore stopping the JVM.
如果没有更多的非守护线程正在运行,则 JVM 存在。默认情况下,唯一的非守护线程是主线程,它在您离开该main
方法时结束,因此停止 JVM。
So eitherdon't end the main thread (by not letting the main
method return) orcreate a new non-daemon thread that never returns (at least not until you wantthe JVM to end).
因此,要么不要结束主线程(通过不让main
方法返回),要么创建一个永不返回的新非守护线程(至少在您希望JVM 结束之前不会)。
Since that rule is actually quite sensible there is usuallya perfect candidate for such a thread. For a HTTP server, for example that could be the thread that actually accepts connections and hands them off to other threads for further processing. As long as that code is running, the JVM will continue running, even if the main
method has long since finished running.
由于该规则实际上非常明智,因此通常有这样一个线程的完美候选者。例如,对于 HTTP 服务器,这可能是实际接受连接并将它们交给其他线程以进行进一步处理的线程。只要该代码正在运行,JVM 就会继续运行,即使该main
方法已经运行很久了。
回答by Stephen C
@Joachim's answer is correct.
@Joachim 的回答是正确的。
But if (for some reason) you still want to block the main method indefinitely (without polling), then you can do this:
但是如果(出于某种原因)你仍然想无限期地阻塞 main 方法(不轮询),那么你可以这样做:
public static void main(String[] args) {
// Set up ...
try {
Object lock = new Object();
synchronized (lock) {
while (true) {
lock.wait();
}
}
} catch (InterruptedException ex) {
}
// Do something after we were interrupted ...
}
Since the lock object is only visible to this method, nothing can notify
it, so the wait()
call won't return. However, some other thread could still unblock the main
thread ... by interrupting it.
由于锁对象只对这个方法可见,notify
它什么都不能,所以wait()
调用不会返回。然而,其他一些线程仍然可以解除对main
线程的阻塞……通过中断它。
回答by yshavit
while (true) { ... }
should go on for a pretty long time. Of course, you'll have to figure out some way of stopping it eventually.
while (true) { ... }
应该会持续很长时间。当然,你最终必须想办法阻止它。
A common trick is to have some volatile boolean running = true
, then have the main loop be while (running) { ... }
and define some criteria by which a thread sets running = false
.
一个常见的技巧是先设置一些volatile boolean running = true
,然后设置主循环while (running) { ... }
并定义线程设置的一些标准running = false
。
回答by Sven Holzinger
Back to Threads, thats exactly what i wanted. Btw this awesome tutorialhelped me a lot.
回到线程,这正是我想要的。顺便说一句,这个很棒的教程对我帮助很大。
Main.java
主程序
public class Main {
public static void main(String args[]) {
ChatServer server = null;
/*if (args.length != 1)
System.out.println("Usage: java ChatServer port");
else*/
server = new ChatServer(Integer.parseInt("8084"));
}
}
and ChatServer.java Class extends a Runnable
和 ChatServer.java 类扩展了一个 Runnable
public class ChatServer implements Runnable
{ private ChatServerThread clients[] = new ChatServerThread[50];
private ServerSocket server = null;
private Thread thread = null;
private int clientCount = 0;
public ChatServer(int port)
{ try
{ System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
start(); }
catch(IOException ioe)
{
System.out.println("Can not bind to port " + port + ": " + ioe.getMessage()); }
}
public void start() {
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}
.... pleas continue with the tutorial
So in the main Method a Runnable is being instantiated and a new Thread as shown inpublic void start() {
is being instantiated with the runnable.
That cases the JVM to continue executing the process until you quit the project or the debugger.
所以在主方法中,一个 Runnable 正在被实例化,一个如图所示的新线程public void start() {
正在用 runnable 实例化。这会导致 JVM 继续执行该过程,直到您退出项目或调试器。
Btw thats the same as Joachim Sauer posted in his answere.
顺便说一句,这与 Joachim Sauer 在他的回答中发布的相同。
回答by Madhu Stv
Also we can achieve the same with the ReentrantLock and call wait() on it:
我们也可以使用 ReentrantLock 实现相同的效果,并在其上调用 wait():
public class Test{
private static Lock mainThreadLock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
System.out.println("Stop me if you can");
synchronized (mainThreadLock) {
mainThreadLock.wait();
}
}