Вопрос

В моем приложении есть домашний веб-сервер. Этот веб-сервер создает новый поток для каждого запроса, который поступает в сокет для принятия. Я хочу, чтобы веб-сервер ждал, пока не будет достигнута конкретная точка в потоке, который он только что создал.

Я просмотрел множество сообщений на этом сайте и примеров в Интернете, но не могу заставить веб-сервер продолжить работу после того, как я скажу ветке подождать. Базовый пример кода был бы великолепен.

Является ли синхронизированное ключевое слово правильным способом? Если да, то как этого достичь? Ниже приведены примеры кода моего приложения:

Веб-сервер

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 ):

Часть веб-сервера

// 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 Состояние . Из документов:

  

Условия (также известные как условие   очереди или условные переменные) обеспечивают   средство для приостановки одного потока   выполнение («ждать») до получения уведомления   другим потоком, что некоторые государства   Теперь условие может быть выполнено.

Запустить под отладчиком и установить точку останова?

Если это невозможно, то прочитать строку из System.in?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top