8

私はこのコードを取りました:

 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アプリケーションを起動するときにも機能しますか?コマンドラインから手動で起動するのではありませんか?

HTTP接続をリッスンするJavaアプリケーションを作成したいと思います。システムの起動時にアプリケーションが自動的に起動します(UNIX rcスクリプトを使用)。これは、意図的に停止するまで、アプリケーションが継続的に実行されることを意味します。理論的には永久に実行されます。これをJavamain()メソッドで実装するための最良の方法は何ですか?

4

7 に答える 7

38

それは奇妙な黒魔術のように見えますが、以下は非常にエレガントな方法でトリックを行います

Thread.currentThread().join();

その結果、mainたとえば、現在のスレッドは、join()スレッドmain、つまりそれ自体が終了するのを待ちます。デッドロック。

もちろん、ブロックされたスレッドはデーモンスレッドであってはなりません。

于 2015-11-03T15:10:22.063 に答える
17

mainメソッドをJavaのままにしておいても、プログラムは自動的に終了しません。

デーモン以外のスレッドが実行されていない場合、JVMは存在します。デフォルトでは、デーモン以外のスレッドはメインスレッドのみであり、mainメソッドを終了すると終了するため、JVMが停止します。

したがって、メインスレッドを終了しない(メソッドを返さないようにする)(少なくともJVMを終了するまでは)戻らない新しい非デーモンスレッドを作成します。main

そのルールは実際には非常に賢明なので、通常、そのようなスレッドの完璧な候補があります。たとえば、HTTPサーバーの場合、実際に接続を受け入れ、さらに処理するために他のスレッドにそれらを渡すスレッドである可能性があります。そのコードが実行されている限り、mainメソッドの実行が終了してから長い時間が経過していても、JVMは実行を継続します。

于 2012-08-30T14:22:07.893 に答える
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スレッドを中断することで、スレッドのブロックを解除できます。

于 2012-08-30T14:43:52.733 に答える
1

while (true) { ... }かなり長い間続くはずです。もちろん、最終的にはそれを止める方法を考え出す必要があります。

一般的なトリックは、いくつかをvolatile boolean running = true持ってから、メインループを持ってwhile (running) { ... }、スレッドが設定するいくつかの基準を定義することrunning = falseです。

于 2012-08-30T14:22:23.437 に答える
1

スレッドに戻ると、まさにそれが私が望んでいたことです。ところで、この素晴らしいチュートリアルは私を大いに助けてくれました。

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がインスタンス化され、に示すような新しいスレッドがRunnableでインスタンス化さ
public void start() { れます。その場合、JVMは、プロジェクトまたはデバッガーを終了するまでプロセスの実行を継続します。

ところで、それはヨアヒムザウアーが彼の回答に投稿したのと同じです。

于 2016-04-27T08:42:36.297 に答える
0

デーモン以外のスレッドが実行されていない場合、Javaプログラムは終了します。必要なのは、そのような実行中のスレッドを1つ持つことだけです。無限ループを使用してそれを行うこともできますが、それはCPUサイクルを消費します。以下はそれを行うための合理的な方法のようです。

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {}); //submit a task that does what you want (in this case, nothing)
于 2021-12-25T10:51:16.390 に答える
-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();
 }
}
于 2019-08-30T12:31:53.000 に答える