如何在Java中永远运行程序? System.in.read()是唯一的方法吗?

时间:2012-08-30 14:19:12

标签: java

我带了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     } 

第33行“System.in.read()”是否意味着它会阻塞直到有输入?使用UNIX rc脚本启动Java应用程序时这是否也有效 - 不是从命令行手动启动的?

我想编写一个Java应用程序来监听HTTP连接。系统引导时将自动启动应用程序(使用UNIX rc脚本)。这意味着应用程序将持续运行 - 理论上永远,直到有目的地停止。在Java main()方法中实现它的最佳方法是什么?

6 个答案:

答案 0 :(得分:22)

它看起来像一个奇怪的黑魔法,但是以非常优雅的方式完成了这个技巧

Thread.currentThread().join();

因此,当前线程main等待join()线程main,这本身就是结束。僵持。

当然,被阻止的线程不能是守护程序线程。

答案 1 :(得分:14)

main方法保留在Java中 not 会自动结束该程序。

如果没有正在运行的非守护程序线程,则存在JVM。默认情况下,唯一的非守护程序线程是主线程,它在您离开main方法时结束,因此停止JVM。

所以要么不要结束主线程(不要让main方法返回)创建一个永不返回的新非守护进程线程(至少在你希望 JVM结束之前)。

由于该规则实际上非常明智,通常是这种线程的完美候选者。对于HTTP服务器,例如,它可以是实际接受连接的线程,并将它们移交给其他线程以进行进一步处理。只要该代码正在运行,即使main方法早已完成运行,JVM也将继续运行。

答案 2 :(得分:5)

@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调用将不会返回。但是,其他一些线程仍然可以通过中断它来取消阻塞{{1}}线程。

答案 3 :(得分:1)

while (true) { ... }应该会持续很长时间。当然,你最终必须想出一些阻止它的方法。

一个常见的诀窍是拥有一些volatile boolean running = true,然后让主循环为while (running) { ... }并定义线程设置running = false的一些标准。

答案 4 :(得分:1)

回到主题,这正是我想要的。顺便说一下这个很棒的tutorial给了我很多帮助。

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和一个新的Thread,如图所示 public void start() { 正在使用runnable进行实例化。 这就是JVM在您退出项目或调试器之前继续执行该过程。

顺便说一句,就像Joachim Sauer在他的回答中所说的一样。

答案 5 :(得分:-1)

我们也可以使用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();
 }
}