我的应用程序中有一个自制的Web服务器。此Web服务器为进入要接受的套接字的每个请求生成一个新线程。我希望Web服务器等到它刚创建的线程中的特定点被命中。

我已经浏览过本网站上的很多帖子和网络上的例子,但是在我告诉线程等待之后,无法继续使用Web服务器。一个基本的代码示例会很棒。

synchronized关键字是否是正确的方法?如果是这样,怎么能实现呢?代码示例在我的应用程序下面:

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 )中的方法:

网络服务器部分

// 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