質問

私のアプリには自家製のWebサーバーがあります。この Web サーバーは、ソケットに入って受け入れられるリクエストごとに新しいスレッドを生成します。Web サーバーには、作成したばかりのスレッド内で特定のポイントがヒットするまで待機してもらいたいと考えています。

このサイトの多くの投稿や Web 上の例を調べてきましたが、スレッドに待機するように指示した後、Web サーバーを続行させることができません。基本的なコード例は素晴らしいでしょう。

synchronized キーワードはこれを解決する正しい方法ですか?もしそうなら、どうすればこれを達成できるでしょうか?私のアプリのコード例は以下のとおりです。

ウェブサーバー

while (true) {
  //block here until a connection request is made
  socket = server_socket.accept();

  try {
    //create a new HTTPRequest object for every file request
    HttpRequest request = new HttpRequest(socket, this);

    //create a new thread for each request
    Thread thread = new Thread(request);

    //run the thread and have it return after complete
    thread.run();

    ///////////////////////////////
    wait here until notifed to proceed
    ///////////////////////////////
  } catch (Exception e) {
    e.printStackTrace(logFile);
  }
}

スレッドコード

public void run() {
  //code here

  //notify web server to continue here
}

更新 - 最終的なコードは次のとおりです。の HttpRequest 電話するだけです resumeListener.resume() 応答ヘッダーを送信するたびに (もちろん、インターフェースを別のクラスとして追加し、 addResumeListener(ResumeListener r1) のメソッド HttpRequest):

Webサーバー部分

// server infinite loop
while (true) {

  //block here until a connection request is made
  socket = server_socket.accept();

  try {
    final Object locker = new Object();

    //create a new HTTPRequest object for every file request
    HttpRequest request = new HttpRequest(socket, this);

    request.addResumeListener(new ResumeListener() {
      public void resume() {
        //get control of the lock and release the server
        synchronized(locker) {
          locker.notify();
        }
      }
    });

    synchronized(locker) {
      //create a new thread for each request
      Thread thread = new Thread(request);

      //run the thread and have it return after complete
      thread.start();

      //tell this thread to wait until HttpRequest releases
      //the server
      locker.wait();
    }
  } catch (Exception e) {
    e.printStackTrace(Session.logFile);
  }
}
役に立ちましたか?

解決

まず最初に、ここで車輪の再発明を行うと、さまざまな問題が発生する可能性が高いという他の人の意見に私も同意します。しかし、とにかくこの道を進みたいのであれば、やろうとしていることは難しいことではありません。Jetty を試してみたことがありますか?

おそらく次のようなものでしょう:

public class MyWebServer {

  public void foo() throws IOException {
    while (true) {
      //block here until a connection request is made
      ServerSocket socket = new ServerSocket();

      try {
        final Object locker = new Object();
        //create a new HTTPRequest object for every file request
        MyRequest request = new MyRequest(socket);
        request.addResumeListener(new ResumeListener() {
          public void resume() {
            locker.notify();
          }
        });
        synchronized(locker){

          //create a new thread for each request
          Thread thread = new Thread(request);

          //start() the thread - not run()
          thread.start();

          //this thread will block until the MyRequest run method calls resume
          locker.wait();
        }  
      } catch (Exception e) {
      }

    }
  }
}

public interface ResumeListener {
  public void resume();
}

public class MyRequest implements Runnable{
  private ResumeListener resumeListener;

  public MyRequest(ServerSocket socket) {
  }

  public void run() {
    // do something
    resumeListener.resume(); //notify server to continue accepting next request
  }

  public void addResumeListener(ResumeListener rl) {
    this.resumeListener = rl;
  }
}

他のヒント

java.util.concurrentを使用できます。 .CountDownLatch の場合、カウントは1です。インスタンスを作成して、親スレッドと子スレッドで共有するようにします(たとえば、 HttpRequest のコンストラクターで作成し、メンバー関数で取得できるようにします)。次にサーバーは await()を呼び出し、親を解放する準備ができるとスレッドは countDown()をヒットします。

おそらくJavaを使用する必要があります条件。ドキュメントから:

  

条件(条件とも呼ばれる   キューまたは条件変数)提供   1つのスレッドが中断するための手段   通知されるまで実行(「待機」)   ある状態の別のスレッドによって   条件が真になる可能性があります。

デバッガーで実行し、ブレークポイントを設定しますか?

実行不可能な場合は、System.inから行を読みます

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top