簡體   English   中英

Java中線程的同步

[英]Synchronization in threads for Java

我的應用程序中有一個自制的Web服務器。 此Web服務器為進入要接受的套接字的每個請求生成一個新線程。 我希望Web服務器等到它剛創建的線程中的特定點被命中。

我已經瀏覽過本網站上的很多帖子和網絡上的例子,但在告訴線程等待之后,我無法繼續使用Web服務器。 一個基本的代碼示例會很棒。

synchronized關鍵字是正確的方法嗎? 如果是這樣,怎么能實現呢? 代碼示例在我的應用程序下面:

網絡服務器

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

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

您可以使用java.util.concurrent.CountDownLatch ,計數為1。 安排由父線程和子線程創建和共享的實例(例如,在HttpRequest的構造函數中創建它,並使其可由成員函數檢索)。 然后服務器在其上調用await() ,當線程准備釋放其父節點時,線程會點擊countDown()

您可能需要使用Java Condition 來自文檔:

條件(也稱為條件隊列或條件變量)為一個線程提供暫停執行(“等待”)的手段,直到另一個線程通知某個狀態條件現在可能為真。

首先,我贊同其他人的觀點,即在這里重新發明輪子很可能會為你帶來各種各樣的問題。 但是,如果你想沿着這條路走下去,那么你要做的事情並不困難。 您是否嘗試過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;
  }
}

在調試器下運行並設置斷點?

如果不可行,那么從System.in讀取一行?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM