2013-08-06 4 views
5

私は、com.sun.net.httpserver.HttpServerを使用してサーバーコードのビットをテストするための小さなコンテナを作成しています。要求を処理するために複数のスレッドを使用することに問題があります。複数のHttpHandlerを並行して作成するためのHttpServerの入手方法

20スレッドのjava.util.concurrent.ThreadPoolExecutorを作成するには、java.util.concurrent.Excutors.newFixedThreadPool(20)を呼び出します。次に、このExecutorをHttpServerに設定します。 Jmeterを使用して、20のクライアントスレッドを起動して、サーバー内の唯一のHttpHandler実装にルーティングする要求を送信します。私は20(またはほぼ20)別のスレッドがここで使用されて参照するだろうと思った

Started TestServer at port 8800 
[email protected] 
[email protected] 
ht[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] 

:そのハンドラがするSystem.out.println(これ)を行い、私はこの出力を見ています。ここにコードがあります。

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

私はHttpServerに複数の同時リクエストを処理するために複数のTestHandlerを並行して作成したいと考えています。私はここで何が欠けていますか?

(その答えは、私はすでにやっているエグゼキュータを使用することですが、ところで、これは、Can I make a Java HttpServer threaded/process requests in parallel?と非常によく似ています。ありがとう。)

+0

エグゼキュータが同じスレッドを再利用し続けることができる十分な速さで各要求が処理される可能性はありますか?変更があるかどうかを確認するためにハンドラに遅延を追加できますか? – elevine

+0

@elevine:私はそれについて考えて、TestHandler.handle(HttpExchange)に 'Thread.sleep(1000)'を追加しました。同じ結果。ありがとう。 – Michael

答えて

2

実行可能なの同じインスタンスを複数回実行することができます異なるスレッド。詳細はInitializing two threads with the same instance of a runnableを参照してください。

あなたの例では、HttpHandler情報が表示されますが、実行中のスレッドについては何も表示されません。また、サーバーがすべてのスレッドに対して常に同じオブジェクトを再利用するため、その情報は変更されません。

あなたが使用できるスレッドIDを印刷したい場合:予想通り

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

スレッドIDを変更する必要があります。

関連する問題