Pregunta

Tengo un servidor web propio en mi aplicación. Este servidor web genera un nuevo hilo para cada solicitud que entra en el socket para ser aceptada. Quiero que el servidor web espere hasta que se toque un punto específico en el hilo que acaba de crear.

He visto muchas publicaciones en este sitio y ejemplos en la web, pero no puedo hacer que el servidor web continúe después de haberle dicho al hilo que espere. Un ejemplo de código básico sería genial.

¿Es la palabra clave sincronizada la forma correcta de hacerlo? Si es así, ¿cómo se puede lograr esto? Los ejemplos de código están debajo de mi aplicación:

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

Código de hilo

public void run() {
  //code here

  //notify web server to continue here
}

Actualización: el código final es el siguiente. El HttpRequest solo llama a resumeListener.resume () cada vez que envío un encabezado de respuesta (por supuesto, también agrego la interfaz como una clase separada y el addResumeListener (ResumeListener r1 ) método en HttpRequest ):

Parte del servidor 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);
  }
}
¿Fue útil?

Solución

En primer lugar, me hago eco del sentimiento de los demás de que reinventar la rueda aquí probablemente te llevará a una variedad de problemas para ti. Sin embargo, si quieres seguir este camino de todos modos, lo que estás tratando de hacer no es difícil. ¿Has experimentado con Jetty?

Tal vez algo como esto:

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

Otros consejos

Puede usar java.util.concurrent .CountDownLatch con un conteo de 1 para esto. Organice una instancia de la misma para crearla y compartirla con el subproceso principal y secundario (por ejemplo, créela en el constructor de HttpRequest y pídale que la función miembro la pueda recuperar). El servidor luego llama a await () en él, y el hilo golpea a countDown () cuando está listo para liberar a su padre.

Probablemente necesite usar un Java Condición . De los documentos:

  

Condiciones (también conocidas como condición   colas o variables de condición) proporcionan   un medio para un hilo para suspender   ejecución (esperar " esperar ") hasta que se le notifique   por otro hilo que algún estado   La condición ahora puede ser verdadera.

¿Se ejecuta bajo un depurador y establece un punto de interrupción?

Si no es factible, entonces lee una línea de System.in?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top