私は、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?と非常によく似ています。ありがとう。)
エグゼキュータが同じスレッドを再利用し続けることができる十分な速さで各要求が処理される可能性はありますか?変更があるかどうかを確認するためにハンドラに遅延を追加できますか? – elevine
@elevine:私はそれについて考えて、TestHandler.handle(HttpExchange)に 'Thread.sleep(1000)'を追加しました。同じ結果。ありがとう。 – Michael