Domanda

Ho un server web cresciuto nella mia app. Questo web server genera un nuovo thread per ogni richiesta che arriva nel socket per essere accettata. Voglio che il web server aspetti fino a quando un punto specifico non viene raggiunto nel thread appena creato.

Ho passato molti post su questo sito ed esempi sul Web, ma non riesco a far procedere il server Web dopo che ho detto al thread di attendere. Un esempio di codice di base sarebbe fantastico.

La parola chiave sincronizzata è il modo corretto di procedere? In tal caso, come può essere raggiunto? Di seguito sono riportati esempi di codice della mia app:

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

Codice discussione

public void run() {
  //code here

  //notify web server to continue here
}

Aggiornamento: il codice finale è il seguente. Il HttpRequest chiama semplicemente resumeListener.resume () ogni volta che invio un'intestazione di risposta (ovviamente aggiungendo anche l'interfaccia come classe separata e addResumeListener (ResumeListener r1 ) in HttpRequest ):

Parte del server 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);
  }
}
È stato utile?

Soluzione

Prima di tutto, faccio eco al sentimento degli altri che reinventare la ruota qui porterà molto probabilmente a una serie di problemi per te. Tuttavia, se vuoi percorrere questa strada comunque, ciò che stai cercando di fare non è difficile. Hai sperimentato Jetty?

Forse qualcosa del genere:

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

Altri suggerimenti

Puoi utilizzare java.util.concurrent .CountDownLatch con un conteggio di 1 per questo. Predisporre che un'istanza di esso sia creata e condivisa dal thread padre e figlio (ad esempio, crearla nel costruttore di HttpRequest e farlo recuperare da una funzione membro). Il server quindi chiama await () e il thread colpisce countDown () quando è pronto a rilasciare il suo genitore.

Probabilmente dovrai usare un Java Condizione . Dai documenti:

  

Condizioni (noto anche come condizione   code o variabili di condizione)   un mezzo per sospendere un thread   esecuzione (per "attendere") fino alla notifica   da un altro thread che alcuni stati   la condizione potrebbe ora essere vera.

Esegui un debugger e imposta un punto di interruzione?

Se impossibile, leggi una riga da System.in?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top