【发布时间】:2017-06-15 08:16:55
【问题描述】:
我正在制作一个接收 HTTP 请求的 Java 应用程序。对于传入的每个请求,我都会启动一个新线程,并在该线程中读取请求并执行必要的操作。但是,我想阻止用户执行“Slow Loris Attack”,所以我正在考虑给线程一个maxTime 值。如果线程花费的时间超过maxTime,无论如何它都会终止。所以它也会阻止慢速连接,这不是问题。
但是,我不知道这样做的正确方法是什么。我试过下面的代码,但是这段代码阻塞了我的主线程。我正在寻找一种方法来做类似这样的事情,而不会阻塞主线程。
代码:
/**
* Executor which is used for threadpools.
*/
private ExecutorService executor;
/**
* Constructor for the class RequestReceiver.
* Initializes fields.
*/
public RequestReceiver() {
this.executor = Executors.newFixedThreadPool(200);
}
@Override
public void run() {
try {
this.serverSocket = new ServerSocket(port);
} catch (IOException ex) {
Logger.getInstance().logText("Could not start server on port: " + port);
return;
}
Logger.getInstance().logText("Server running at port: " + port);
try {
while (shouldContinue) {
Socket client = serverSocket.accept();
HTTPRequestHandler handler = new HTTPRequestHandler(client);
Thread t = new Thread(handler);
executor.submit(t).get(10, TimeUnit.SECONDS); //This line is blocking
}
} catch (IOException ex) {
Logger.getInstance().logText("Server is shutdown");
} catch (InterruptedException | ExecutionException | TimeoutException ex) {
Logger.getInstance().logText("Thread took too long, it's shutdown");
}
}
【问题讨论】:
-
能否在阻塞语句
executor.submit(t).get(10, TimeUnit.SECONDS);之后立即添加executor.shutdown();并尝试? -
@harshavmb 我不明白这将如何解决我的问题。我确实尝试过,就像我预测的那样它崩溃了。因为当您发送第二个 HTTP 请求时,池不会接受它,因为它已关闭。
java.util.concurrent.RejectedExecutionException -
你为什么在你的主线程上调用 Future#get?你甚至什么都不做。另外,TimeOutException 不会停止任务。
-
@matt 因为我在 SO 上找到了多个答案,说明你可以使用这个。 stackoverflow.com/a/2733370/4653908(见 cmets)。
-
答案还是 cmets?我不遵循您所链接的内容,情况似乎有所不同。我通过示例提供了答案,因此
.get()不会阻塞您的主线程。
标签: java multithreading