2013-08-06 18 views
5

Sunucu kodunun bitlerini test etmek için küçük bir kap oluşturmak için com.sun.net.httpserver.HttpServer kullanıyorum ve istekleri işlemek için birden fazla iş parçacığı kullanmakta sorun yaşıyorum.HttpServer, birden çok HttpHandlers'ı paralel olarak nasıl oluşturur?

Ben 20 iş parçacığı ile bir java.util.concurrent.ThreadPoolExecutor oluşturmak için java.util.concurrent.Executors.newFixedThreadHavuz (20) çağrısı. Sonra bu Executor'ı HttpServer'a ayarlıyorum. Jmeter'ı kullanarak, sunucudaki tek HttpHandler uygulamasına yönlendirilmek üzere bir istek göndermek için 20 istemci iş parçacığını kovarım.

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] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 

farklı ipler burada kullanılıyor Ben 20 (ya da neredeyse 20) görürdünüz düşündüm: O işleyici bir System.out.println (bu) ve bu çıktıyı görüyorum yapar. İşte kod.

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

Birden çok eşzamanlı isteği karşılamak için HttpServer'ın paralel olarak birden çok TestHandler oluşturmasını istiyorum. Burada neyi özlüyorum?

(bunu cevaplamak Zaten yapıyorum bir Executor kullanmaktır olsa BTW, bu, Can I make a Java HttpServer threaded/process requests in parallel? oldukça benzer. Teşekkürler.) Bir çalıştırılabilir aynı örneği birden çok kez çalıştırılabilir

+0

Her isteğin, yürütücünün aynı iş parçacığını yeniden kullanmaya devam edebileceği kadar hızlı işlenmesi mümkün mü? Herhangi bir değişiklik olup olmadığını görmek için işleyicinize biraz gecikme ekleyebilir misiniz? – elevine

+0

@elevine: Bunu düşündüm, TestHandler.handle (HttpExchange) için bir 'Thread.sleep (1000)' eklendi. Aynı sonuç. Teşekkürler. – Michael

cevap

2

farklı konular. Daha fazla bilgi için bkz. Initializing two threads with the same instance of a runnable.

Örneğinizde yazdırdığınız şey, HttpHandler bilgisidir, ancak hangi iş parçacığının çalıştığı hakkında bir şey yoktur. Ve sunucu tüm iş parçacıkları için her zaman aynı nesneyi yeniden kullandığı için bu bilgi değişmez.

Eğer kullanabilirsiniz Konunun İD numarasını yazdırmak istiyorsanız: beklendiği gibi

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

ThreadId değişmelidir.

İlgili konular