首页
学习
活动
专区
圈层
工具
发布

多线程
EN

Stack Overflow用户
提问于 2020-01-07 13:49:09
回答 1查看 1.6K关注 0票数 1

我使用sun.net.httpServer在我的应用程序中运行HTTP(不要问我为什么)。

问题是,它只在一个线程中处理我的请求,所以我的吞吐量是一个灾难。

我想,如果我setExecutor到我的httpServer,这个问题将得到解决,但我开始在我的服务器端和客户端(SOAP)异常。我测试各种各样的执行者,包括Executors.newCachedThreadPoolExecutors.newFixedThreadPoolExecutors.newWorkStealingPoolExecutors.newScheduledThreadPool

正如我说过的,当我从setExecutornull时,我的代码可以正常工作,但是在这个配置中,我的代码过程会依次请求。

该怎么办呢。这是我的代码:

代码语言:javascript
复制
public class HTTPListener {
    private HttpServer httpServer;
    private int port = 1253;

    public void stop() {
        if (httpServer != null) {
            httpServer.stop(0);
            httpServer = null;
        }
    }
    public void startHTTPServer() {
        try {
            httpServer = HttpServer.create(new InetSocketAddress(1252), 100);
            httpServer.setExecutor(null);
            httpServer.createContext("/", new RequestHandler());
            httpServer.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

当我设置执行者时,我会得到这个错误。

代码语言:javascript
复制
java.io.IOException: stream closed
    at sun.net.httpserver.FixedLengthOutputStream.write(FixedLengthOutputStream.java:68)
    at sun.net.httpserver.PlaceholderOutputStream.write(ExchangeImpl.java:444)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    at java.io.FilterOutputStream.close(FilterOutputStream.java:158)
    at com.RequestHandler.sendResponse(RequestHandler.java:61)
    at com..RequestHandler.handle(RequestHandler.java:18)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
    at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82)
    at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
    at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:645)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

这是我的RequestHandler课程:

代码语言:javascript
复制
public class RequestHandler implements HttpHandler {
    private HttpExchange sender;

    @Override
    public void handle(HttpExchange httpExchange) throws IOException {
        this.sender = httpExchange;
        try {
            String request = readRequestBody();
            sendResponse(200, "Hello World !");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            this.sender.close();
        }
    }

    private String readRequestBody() throws Exception {
        try (InputStream isr = sender.getRequestBody()) {
            byte[] buffer = new byte[isr.available()];
            isr.read(buffer);
            return Arrays.toString(buffer);
        } catch (IOException ex) {
            throw new Exception(ex.getMessage());
        }
    }

    private void sendResponse(int httpResponseCode, String response) throws IOException {
        OutputStream outputStream = null;
        try {
            sender.getResponseHeaders().set("Content-Type", "text/html; charset=UTF-8");
            sender.sendResponseHeaders(httpResponseCode, response.length());
            outputStream = sender.getResponseBody();
            outputStream.write(response.getBytes());
        } finally {
            if (outputStream != null)
                outputStream.close();
        }

    }
}

我还得到了客户端的错误代码。

代码语言:javascript
复制
org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 13; received: 0
    at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:180)
    at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:137)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.Reader.read(Reader.java:140)
    at org.apache.http.util.EntityUtils.toString(EntityUtils.java:247)
    at org.apache.http.util.EntityUtils.toString(EntityUtils.java:291)
    at Business.HTTPHandler.Client.send(Client.java:68)
    at main.Main.lambda$main$1(Main.java:86)
    at java.lang.Thread.run(Thread.java:745)

    org.apache.http.client.ClientProtocolException
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
    at Business.HTTPHandler.Client.send(Client.java:67)
    at main.Main.lambda$main$1(Main.java:86)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.http.ProtocolException: Invalid header: *
    at org.apache.http.impl.io.AbstractMessageParser.parseHeaders(AbstractMessageParser.java:232)
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:268)
    at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165)
    at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    ... 5 more

    Caused by: org.apache.http.ProtocolException: Invalid header: 13
    at org.apache.http.impl.io.AbstractMessageParser.parseHeaders(AbstractMessageParser.java:232)
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:268)
    at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165)
    at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    ... 5 more
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-07 14:33:57

您的RequestHandler类不是线程安全的,这就是为什么当您运行单个线程时,它可以工作,而在使用执行器时失败。

而不是HttpExchange对象存储在sender变量中。当所有线程都覆盖相同的变量,并且可能在错误的状态中看到错误的对象(例如,一个已经关闭流的对象)时,它会导致一个争用条件。

您可以将它作为参数传递给您的方法。你真的不需要额外的变量。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59629716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档