5

アプリに自家製の Web サーバーがあります。この Web サーバーは、受け入れられるソケットに入ってくるすべての要求に対して新しいスレッドを生成します。作成したばかりのスレッドで特定のポイントに到達するまで Web サーバーを待機させたい。

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

同期されたキーワードはこれについて正しい方法ですか? もしそうなら、どうすればこれを達成できますか?コード例は私のアプリの下にあります:

ウェブサーバー

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);
  }
}
4

4 に答える 4

7

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

于 2009-09-10T20:30:27.423 に答える
3

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

条件(条件キューまたは条件変数とも呼ばれます)は、ある状態条件が真になる可能性があることを別のスレッドから通知されるまで、あるスレッドが実行を一時停止する(「待機する」)ための手段を提供します。

于 2009-09-10T20:32:23.803 に答える
1

まず第一に、ここで車輪の再発明を行うと、さまざまな問題が発生する可能性が高いという他の人の感情を反映しています。しかし、とにかくこの道を進みたいのなら、あなたがやろうとしていることは難しくありません。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;
  }
}
于 2009-09-10T21:53:36.823 に答える
-3

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

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

于 2009-09-10T20:57:06.883 に答える