无法使我的 Http Server 多线程化?我正在使用 Java HttpServer API
Unable to make my Http Server multithreaded? I'm using Java HttpServer API
我有以下代码片段可以使我的 HttpServer 成为多线程服务器,但它仍然以单线程方式工作 threaded.Can 你能帮帮我吗?我正在使用 Java HttpServer API :
// Bind to port 8083
httpServer = HttpServer.create(new InetSocketAddress(HTTP_PORT), 0);
// Adding '/send' context
httpServer.createContext("/send", new SendHandler());
ExecutorService executor = Executors.newCachedThreadPool();
httpServer.setExecutor(executor);
// Start the server
httpServer.start();
完整 Java Class :
public class GCMMockServer {
static HttpServer httpServer;
static final int HTTP_PORT = 8083;
public static void main(String[] args) {
GCMMockServer.start();
}
public static void start() {
try {
// Bind to port 8083
httpServer = HttpServer.create(new InetSocketAddress(HTTP_PORT), 0);
// Adding '/send' context
httpServer.createContext("/send", new SendHandler());
ExecutorService executor = Executors.newCachedThreadPool();
httpServer.setExecutor(executor);
// Start the server
httpServer.start();
System.out.println("GCM Mock Server started at (localhost,8083)");
} catch (IOException ex) {
Logger.getLogger(GCMMockServer.class.getName()).log(Level.SEVERE,
null, ex);
}
}
public static void stop() {
httpServer.stop(5);
}
// Handler for '/send' context
static class SendHandler implements HttpHandler {
@Override
public void handle(HttpExchange he) throws IOException {
System.out.println("Serving the request");
// Serve for POST requests only
if (he.getRequestMethod().equalsIgnoreCase("POST")) {
try {
// REQUEST Headers
Headers requestHeaders = he.getRequestHeaders();
Set<Map.Entry<String, List<String>>> entries = requestHeaders
.entrySet();
System.out.println("Inside POST method");
int contentLength = Integer.parseInt(requestHeaders
.getFirst("Content-length"));
List<String> contentTypes = null;
for (Iterator<Entry<String, List<String>>> iterator = entries
.iterator(); iterator.hasNext();) {
Entry<String, List<String>> entry = iterator.next();
String key = entry.getKey();
System.out.println("Key : " + key + ", values : ");
if (key.equalsIgnoreCase("Content-type")) {
contentTypes = entry.getValue();
}
for (Iterator<String> iterator2 = entry.getValue()
.iterator(); iterator2.hasNext();) {
String value = iterator2.next();
System.out.println("-----------" + value);
}
}
System.out.println("Content length : " + contentLength);
// REQUEST Body
InputStream is = he.getRequestBody();
if (contentTypes.contains("application/json")) {
InputStreamReader isr = new InputStreamReader(is,
"utf-8");
BufferedReader br = new BufferedReader(isr);
// From now on, the right way of moving from bytes to
// utf-8 characters:
int b;
StringBuilder buf = new StringBuilder(512);
while ((b = br.read()) != -1) {
buf.append((char) b);
}
JSONObject req = new JSONObject(buf.toString());
System.out.println("Request body : " + req);
String to = (String) req.get("to");
String message = (String) ((JSONObject) req.get("data"))
.get("message");
System.out.println("Request message : " + message
+ ", to : " + to);
}
// RESPONSE Headers
Headers responseHeaders = he.getResponseHeaders();
System.out.println("Response Headers : "
+ responseHeaders.toString());
String response = "Message received";
// Send RESPONSE Headers
he.sendResponseHeaders(HttpURLConnection.HTTP_OK,
response.length());
// RESPONSE Body
OutputStream os = he.getResponseBody();
os.write(response.getBytes());
is.close();
os.flush();
os.close();
he.close();
} catch (Exception e) {
e.printStackTrace();
}
} else if (he.getRequestMethod().equalsIgnoreCase("GET")) {
System.out.println("Nothing to serve in GET request type");
// RESPONSE Headers
Headers responseHeaders = he.getResponseHeaders();
String response = "Hi This is Sandeep";
System.out.println("Response Headers : "
+ responseHeaders.toString());
// Send RESPONSE Headers
he.sendResponseHeaders(HttpURLConnection.HTTP_OK,
response.length());
// RESPONSE Body
OutputStream os = he.getResponseBody();
OutputStreamWriter osw = new OutputStreamWriter(os);
osw.write(response);
// is.close();
osw.close();
os.close();
he.close();
}
}
}
}
考虑更改 handle
方法的开始:
@Override
public void handle(HttpExchange he) throws IOException {
System.out.println("Serving the request from Thread "
+ Thread.currentThread().getName() + " / "
+ Thread.currentThread().getId());
try {
Thread.sleep(5000);
} catch(InterruptedException ie) {
ie.printStackTrace();
return;
}
System.out.println("Continue request in Thread "
+ Thread.currentThread().getName() + " / "
+ Thread.currentThread().getId());
现在启动服务器,打开浏览器,加载您的 url,在 5 秒内刷新两次并查看您的控制台日志。
我感觉你会看到多个线程就好了。
关于您的测试:
您使用的测试是单线程(一个for
循环)。因此,在任何一次 时,您的 servlet 将只有 一个活动调用。由于 for
循环的下一次迭代只会在最后一次完成后开始,因此执行程序线程池中的前一个线程被回收。根据您的测试,不需要多线程。
我有以下代码片段可以使我的 HttpServer 成为多线程服务器,但它仍然以单线程方式工作 threaded.Can 你能帮帮我吗?我正在使用 Java HttpServer API :
// Bind to port 8083
httpServer = HttpServer.create(new InetSocketAddress(HTTP_PORT), 0);
// Adding '/send' context
httpServer.createContext("/send", new SendHandler());
ExecutorService executor = Executors.newCachedThreadPool();
httpServer.setExecutor(executor);
// Start the server
httpServer.start();
完整 Java Class :
public class GCMMockServer {
static HttpServer httpServer;
static final int HTTP_PORT = 8083;
public static void main(String[] args) {
GCMMockServer.start();
}
public static void start() {
try {
// Bind to port 8083
httpServer = HttpServer.create(new InetSocketAddress(HTTP_PORT), 0);
// Adding '/send' context
httpServer.createContext("/send", new SendHandler());
ExecutorService executor = Executors.newCachedThreadPool();
httpServer.setExecutor(executor);
// Start the server
httpServer.start();
System.out.println("GCM Mock Server started at (localhost,8083)");
} catch (IOException ex) {
Logger.getLogger(GCMMockServer.class.getName()).log(Level.SEVERE,
null, ex);
}
}
public static void stop() {
httpServer.stop(5);
}
// Handler for '/send' context
static class SendHandler implements HttpHandler {
@Override
public void handle(HttpExchange he) throws IOException {
System.out.println("Serving the request");
// Serve for POST requests only
if (he.getRequestMethod().equalsIgnoreCase("POST")) {
try {
// REQUEST Headers
Headers requestHeaders = he.getRequestHeaders();
Set<Map.Entry<String, List<String>>> entries = requestHeaders
.entrySet();
System.out.println("Inside POST method");
int contentLength = Integer.parseInt(requestHeaders
.getFirst("Content-length"));
List<String> contentTypes = null;
for (Iterator<Entry<String, List<String>>> iterator = entries
.iterator(); iterator.hasNext();) {
Entry<String, List<String>> entry = iterator.next();
String key = entry.getKey();
System.out.println("Key : " + key + ", values : ");
if (key.equalsIgnoreCase("Content-type")) {
contentTypes = entry.getValue();
}
for (Iterator<String> iterator2 = entry.getValue()
.iterator(); iterator2.hasNext();) {
String value = iterator2.next();
System.out.println("-----------" + value);
}
}
System.out.println("Content length : " + contentLength);
// REQUEST Body
InputStream is = he.getRequestBody();
if (contentTypes.contains("application/json")) {
InputStreamReader isr = new InputStreamReader(is,
"utf-8");
BufferedReader br = new BufferedReader(isr);
// From now on, the right way of moving from bytes to
// utf-8 characters:
int b;
StringBuilder buf = new StringBuilder(512);
while ((b = br.read()) != -1) {
buf.append((char) b);
}
JSONObject req = new JSONObject(buf.toString());
System.out.println("Request body : " + req);
String to = (String) req.get("to");
String message = (String) ((JSONObject) req.get("data"))
.get("message");
System.out.println("Request message : " + message
+ ", to : " + to);
}
// RESPONSE Headers
Headers responseHeaders = he.getResponseHeaders();
System.out.println("Response Headers : "
+ responseHeaders.toString());
String response = "Message received";
// Send RESPONSE Headers
he.sendResponseHeaders(HttpURLConnection.HTTP_OK,
response.length());
// RESPONSE Body
OutputStream os = he.getResponseBody();
os.write(response.getBytes());
is.close();
os.flush();
os.close();
he.close();
} catch (Exception e) {
e.printStackTrace();
}
} else if (he.getRequestMethod().equalsIgnoreCase("GET")) {
System.out.println("Nothing to serve in GET request type");
// RESPONSE Headers
Headers responseHeaders = he.getResponseHeaders();
String response = "Hi This is Sandeep";
System.out.println("Response Headers : "
+ responseHeaders.toString());
// Send RESPONSE Headers
he.sendResponseHeaders(HttpURLConnection.HTTP_OK,
response.length());
// RESPONSE Body
OutputStream os = he.getResponseBody();
OutputStreamWriter osw = new OutputStreamWriter(os);
osw.write(response);
// is.close();
osw.close();
os.close();
he.close();
}
}
}
}
考虑更改 handle
方法的开始:
@Override
public void handle(HttpExchange he) throws IOException {
System.out.println("Serving the request from Thread "
+ Thread.currentThread().getName() + " / "
+ Thread.currentThread().getId());
try {
Thread.sleep(5000);
} catch(InterruptedException ie) {
ie.printStackTrace();
return;
}
System.out.println("Continue request in Thread "
+ Thread.currentThread().getName() + " / "
+ Thread.currentThread().getId());
现在启动服务器,打开浏览器,加载您的 url,在 5 秒内刷新两次并查看您的控制台日志。
我感觉你会看到多个线程就好了。
关于您的测试:
您使用的测试是单线程(一个for
循环)。因此,在任何一次 时,您的 servlet 将只有 一个活动调用。由于 for
循环的下一次迭代只会在最后一次完成后开始,因此执行程序线程池中的前一个线程被回收。根据您的测试,不需要多线程。