2013-08-06 29 views
5

Tôi đang sử dụng com.sun.net.httpserver.HttpServer để tạo một vùng chứa nhỏ để thử nghiệm các bit của mã máy chủ và đang gặp sự cố khi sử dụng nhiều hơn một chuỗi để xử lý các yêu cầu.Làm thế nào để có được HttpServer để tạo ra nhiều HttpHandlers song song?

Tôi gọi java.util.concurrent.Executors.newFixedThreadPool (20) để tạo java.util.concurrent.ThreadPoolExecutor với 20 chuỗi. Sau đó, tôi thiết lập Executor này trên HttpServer. Sử dụng Jmeter, tôi kích hoạt 20 đề tài máy khách để gửi một yêu cầu được định tuyến tới việc thực hiện HttpHandler duy nhất trong máy chủ. Trình xử lý đó thực hiện một System.out.println (điều này) và tôi thấy kết quả này:

Started TestServer at port 8800 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
http.TestHa[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 

Tôi nghĩ rằng tôi sẽ thấy 20 (hoặc gần 20) chủ đề khác nhau đang được sử dụng ở đây. Đây là mã.

package http; 

import java.io.IOException; 
import java.io.OutputStream; 
import java.net.InetSocketAddress; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ExecutorService; 

import com.sun.net.httpserver.HttpExchange; 
import com.sun.net.httpserver.HttpHandler; 
import com.sun.net.httpserver.HttpServer; 

public class TestServer implements Runnable { 

    private final static int PORT = Integer.getInteger("test.port", 8800); 
    private static TestServer serverInstance; 
    private HttpServer  httpServer; 
    private ExecutorService executor; 

    @Override 
    public void run() { 
     try { 
      executor = Executors.newFixedThreadPool(20); 

      httpServer = HttpServer.create(new InetSocketAddress(PORT), 0); 
      httpServer.createContext("/test", new TestHandler()); 
      httpServer.setExecutor(executor); 
      httpServer.start(); 
      System.out.println("Started TestServer at port " + PORT); 

      // Wait here until notified of shutdown. 
      synchronized (this) { 
       try { 
        this.wait(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } catch (Throwable t) { 
      t.printStackTrace(); 
     } 
    } 

    static void shutdown() { 

     try { 
      System.out.println("Shutting down TestServer.");    
      serverInstance.httpServer.stop(0); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     synchronized (serverInstance) { 
      serverInstance.notifyAll(); 
     } 

    } 

    public static void main(String[] args) throws Exception { 

     serverInstance = new TestServer(); 

     Thread serverThread = new Thread(serverInstance); 
     serverThread.start(); 

     Runtime.getRuntime().addShutdownHook(new OnShutdown()); 

     try { 
      serverThread.join(); 
     } catch (Exception e) { } 
    } 

} 

/* Responds to the /test URI. */ 
class TestHandler implements HttpHandler { 

    boolean debug = Boolean.getBoolean("test.debug"); 

    public void handle(HttpExchange exchange) throws IOException { 

     System.out.println(this); // ALWAYS SAME THREAD! 

     String response = "RESPONSE AT " + System.currentTimeMillis(); 

     exchange.sendResponseHeaders(200, response.length()); 
     OutputStream os = exchange.getResponseBody(); 
     os.write(response.getBytes()); 
     os.flush(); 
     os.close(); 
    } 
} 

/* Responds to a JVM shutdown by stopping the server. */ 
class OnShutdown extends Thread { 
    public void run() { 
     TestServer.shutdown(); 
    } 
} 

Tôi muốn HttpServer tạo nhiều TestHandlers song song với dịch vụ nhiều yêu cầu đồng thời. Tôi đang thiếu gì ở đây?

(BTW, đây là khá giống với Can I make a Java HttpServer threaded/process requests in parallel?, mặc dù câu trả lời cho đó là sử dụng một Executor, mà tôi đang đã làm. Cảm ơn.)

+0

Có thể mỗi yêu cầu được xử lý đủ nhanh nơi người thực thi có thể tiếp tục sử dụng lại cùng một chuỗi không? Bạn có thể thêm một số chậm trễ vào trình xử lý của mình để xem liệu có bất kỳ điều gì thay đổi không? – elevine

+0

@elevine: Tôi đã nghĩ về điều đó, vì vậy hãy thêm 'Thread.sleep (1000)' vào TestHandler.handle (HttpExchange). Cùng một kết quả. Cảm ơn. – Michael

Trả lời

2

Các ví dụ tương tự của một Runnable có thể chạy nhiều lần trong chủ đề khác nhau. Xem Initializing two threads with the same instance of a runnable để biết thêm thông tin.

Những gì bạn đang in trong ví dụ của mình là thông tin HttpHandler nhưng không có gì về chuỗi đang chạy. Và thông tin đó không thay đổi khi máy chủ sử dụng lại cùng một đối tượng cho tất cả các chủ đề.

Nếu bạn muốn in thread id bạn có thể sử dụng:

long threadId = Thread.currentThread().getId(); 
System.out.println(threadId); 

threadid nên thay đổi như mong đợi.

Các vấn đề liên quan