[英]How to run a program forever in Java? Is System.in.read() the only way?
我拿了这个代码:
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 }
第 33 行“System.in.read()”是否意味着它会阻塞直到有输入? 这在使用 UNIX rc 脚本启动 Java 应用程序时也能工作 - 不是从命令行手动启动吗?
我想编写一个 Java 应用程序来监听 HTTP 连接。 该应用程序将在系统启动时自动启动(使用 UNIX rc 脚本)。 这意味着应用程序将持续运行 - 理论上永远,直到有目的地停止。 在 Java main() 方法中实现它的最佳方法是什么?
它看起来像一个奇怪的黑魔法,但以下非常优雅的方式
Thread.currentThread().join();
因此,当前线程(例如, main
join()
等待join()
因为线程main
本身就会结束。 僵持。
被阻塞的线程当然不能是守护程序线程。
在Java中保留main
方法不会自动结束程序。
如果不再运行非守护程序线程,则存在JVM。 默认情况下,唯一的非守护程序线程是主线程,它在您离开main
方法时结束,因此停止JVM。
因此要么不结束主线程(不要让main
方法返回), 要么创建一个永不返回的新非守护进程线程(至少在你希望 JVM结束之前)。
由于该规则实际上非常合理,因此通常有一个完美的候选人可以使用这样的线程。 对于HTTP服务器,例如,它可以是实际接受连接的线程,并将它们移交给其他线程以进行进一步处理。 只要该代码正在运行,JVM将继续运行,即使main
方法早已完成运行。
@Joachim的回答是正确的。
但是如果(由于某种原因)你仍然想要无限期地阻止主方法(没有轮询),那么你可以这样做:
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 ...
}
由于锁定对象仅对此方法可见,因此没有任何内容可以notify
它,因此wait()
调用将不会返回。 但是,其他一些线程仍然可以通过中断来解锁main
线程。
while (true) { ... }
应该会持续很长时间。 当然,你最终必须想出一些阻止它的方法。
一个常见的技巧是让一些volatile boolean running = true
,然后让main循环为while (running) { ... }
并定义一些线程设置running = false
。
回到主题,这正是我想要的。 顺便说一句这个很棒的教程对我帮助很大。
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"));
}
}
和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
因此,在主方法中,实例化了一个Runnable,并且如图所示
public void start() {
正在用runnable实例化。 这就是JVM在您退出项目或调试器之前继续执行该过程的情况。
顺便说一句,就像Joachim Sauer在他的回答中所说的那样。
Java 程序在没有非守护线程运行时终止。 您所需要的只是有一个这样的正在运行的线程。 您可以使用无限循环来做到这一点,但这会消耗 CPU 周期。 以下似乎是一种合理的方法。
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {}); //submit a task that does what you want (in this case, nothing)
我们也可以使用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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.