gpt4 book ai didi

java - 如何让 HttpServer 并行创建多个 HttpHandlers?

转载 作者:搜寻专家 更新时间:2023-10-31 20:28:56 25 4
gpt4 key购买 nike

我正在使用 com.sun.net.httpserver.HttpServer 创建一个小容器来测试服务器代码位,但我无法让它使用多个线程来处理请求。

我调用 java.util.concurrent.Executors.newFixedThreadPool(20) 创建一个具有 20 个线程的 java.util.concurrent.ThreadPoolExecutor。然后,我在 HttpServer 上设置了这个 Executor。使用 Jmeter,我触发了 20 个客户端线程来发送一个请求,该请求将被路由到服务器中唯一的 HttpHandler 实现。该处理程序执行 System.out.println(this) 并且我看到了以下输出:

Started TestServer at port 8800
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa
http.TestHandler@30eb9dfa

我想我会看到这里使用了 20 个(或将近 20 个)不同的线程。这是代码。

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? 非常相似,尽管答案是使用 Executor,我已经在这样做了。谢谢。)

最佳答案

同一可运行实例可以在不同线程中运行多次。参见 Initializing two threads with the same instance of a runnable了解更多信息。

您在示例中打印的是 HttpHandler 信息,但没有关于哪个线程正在运行的信息。并且该信息不会改变,因为服务器始终为所有线程重用相同的对象。

如果你想打印线程id,你可以使用:

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

threadId 应按预期更改。

关于java - 如何让 HttpServer 并行创建多个 HttpHandlers?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18084038/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com