5

我的应用程序中有一个自制的网络服务器。此 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);
  }
}
4

4 回答 4

7

为此,您可以使用计数为 1 的java.util.concurrent.CountDownLatch 。安排它的一个实例由父线程和子线程创建和共享(例如,在HttpRequest的构造函数中创建它,并使其可由成员函数检索)。然后服务器调用它,当它准备好释放它的父线程时await(),线程就会命中。countDown()

于 2009-09-10T20:30:27.423 回答
3

您可能需要使用 Java Condition。从文档:

条件(也称为条件队列或条件变量)为一个线程提供了一种暂停执行(“等待”)的方法,直到另一个线程通知某个状态条件现在可能为真。

于 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 中读取一行?

于 2009-09-10T20:57:06.883 回答