繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM