我正在尝试发送两个帖子请求。两者都应该同时发送(在我下面的当前代码中可能会一个接一个地发送)并且应该等待最多80ms的响应,如果没有请求响应,则将响应视为空。
public void SendRequests(String requestString){
TimeLimiter limiter1 = new SimpleTimeLimiter();
Response response1 = null;
System.out.println("Request Sent to 1");
try{
response1 = limiter1.callWithTimeout(new Callable<Response>() {
public Response call() {
//assume sendPost1 method will send POST request to some server and return response from server
return sendPost1(requestString);
}
}, 80, TimeUnit.MILLISECONDS, true);
}catch(Exception te){
te.printStackTrace();
}
TimeLimiter limiter2 = new SimpleTimeLimiter();
Response response2 = null;
System.out.println("Request Sent to 2");
try{
response2 = limiter2.callWithTimeout(new Callable<Response>() {
public Response call() {
//assume sendPost2 method will send POST request to some server and return response from server
return sendPost2(requestString);
}
}, 80, TimeUnit.MILLISECONDS, true);
}catch(Exception te){
te.printStackTrace();
}
//Do some process using response1 and response2
}
}
我正在寻找一些方法同时发送2个post请求并等待80ms的响应,如果没有响应则将响应视为null。
@Gray 我尝试了你的解决方案如下。首先是几分钟,我的servlet响应时间是2ms-10ms,但在那之后,它突然增加到200-300ms。
@WebServlet("/incomingTraffic")
public class ServletClass extends HttpServlet {
Gson gson;
private static URL url1;
private static URL url2;
public Exchanger() {
super();
}
public void init(ServletConfig config) throws ServletException {
gson = new Gson();
try{
url1 = new URL( Constants.URL1 );
url2 = new URL( Constants.URL2 );
}catch(Exception e){
}
}
public void destroy() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletInputStream inputStream = request.getInputStream();
Reader reader = new InputStreamReader(inputStream);
//Request class is POJO
final Request requestString = gson.fromJson(reader, Request.class);
reader.close();
//long start = System.currentTimeMillis();
TimeLimiter limiter = new SimpleTimeLimiter();
//Response class is POJO
Response response1 = null;
Response response2 = null;
final ExecutorService threadPool = Executors.newCachedThreadPool();
Future<Response> future1 = threadPool.submit(new Callable<Response>() {
public Response call() {
return sendPost1(requestString);
}
});
Future<Response> future2 = null;
if(Some Condition Satisfy){
future2 = threadPool.submit(new Callable<Response>() {
public Response call() {
return sendPost2(requestString);
}
});
}
threadPool.shutdown();
long start = System.currentTimeMillis();
try {
response1 = future1.get(80, TimeUnit.MILLISECONDS);
} catch (ExecutionException ee) {
// job threw exception
} catch (InterruptedException ie) {
// this (main?) thread was interrupted, good pattern to re-interupt
Thread.currentThread().interrupt();
} catch (TimeoutException te) {
// wait timed out, maybe this is right?
response1 = null;
// try to interrupt the thread
future1.cancel(true);
}
if(requestString.getImp().get(0).getVideo() != null){
// wait for 80 MILLISECONDS minus how long we've been waiting for 2nd request
long end = System.currentTimeMillis();
//System.out.println(start+" - "+end);
long wait = 80 + start - end;
if (wait < 0) {
wait = 0;
}
try {
response2 = future2.get(wait, TimeUnit.MILLISECONDS);
} catch (ExecutionException ee) {
// job threw exception
} catch (InterruptedException ie) {
// this (main?) thread was interrupted, good pattern to re-interrupt
Thread.currentThread().interrupt();
} catch (TimeoutException te) {
// wait timed out, maybe this is right?
response2 = null;
// try to interrupt the thread
future2.cancel(true);
}
}
try {
threadPool.awaitTermination(80, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
}
if(response1 == null && response2 == null){
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}else {
response.setContentType("application/json");
PrintWriter output = response.getWriter();
response.setStatus(HttpServletResponse.SC_OK);
if(Some Condition){
response.getWriter().write(gson.toJson(response1));
}
else{
response.getWriter().write(gson.toJson(response1));
}
}
output.flush();
output.close();
}
}
protected Response sendPost2(Request request){
Response response = null;
String str = gson.toJson(request);
HttpURLConnection conn = null;
try{
conn= (HttpURLConnection) url2.openConnection();
conn.setDoOutput( true );
conn.setInstanceFollowRedirects( false );
conn.setRequestMethod( "POST" );
conn.setRequestProperty( "Content-Type", "application/json");
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty( "Content-Length", Integer.toString(str.length()));
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(str);
wr.flush();
wr.close();
int responseCode = conn.getResponseCode();
if(responseCode != 200){
return null;
}
Reader reader = new InputStreamReader(conn.getInputStream());
response = gson.fromJson(reader, Response.class);
conn.disconnect();
}catch(Exception e){
e.printStackTrace();
conn.disconnect();
}
return response;
}
protected Response sendPost1(Request request){
Response response = null;
String str = gson.toJson(request);
HttpURLConnection conn = null;
try{
conn= (HttpURLConnection) url1.openConnection();
conn.setDoOutput( true );
conn.setInstanceFollowRedirects( false );
conn.setRequestMethod( "POST" );
conn.setRequestProperty( "Content-Type", "application/json");
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty( "Content-Length", Integer.toString(str.length()));
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(str);
wr.flush();
wr.close();
int responseCode = conn.getResponseCode();
if(responseCode != 200){
return null;
}
Reader reader = new InputStreamReader(conn.getInputStream());
response = gson.fromJson(reader, Response.class);
conn.disconnect();
}catch(Exception e){
e.printStackTrace();
conn.disconnect();
}
return response;
}
}
答案 0 :(得分:0)
我正在寻找一些方法同时发送2个post请求并等待80ms的响应,如果没有响应则将响应视为null。
您当然可以将Callable<Response>
作业提交到固定或缓存的线程池,然后等待它们完成。类似的东西:
final ExecutorService threadPool = Executors.newCachedThreadPool(NUM_THREADS);
...
Future<Response> future1 = threadPool.submit(new Callable<>() { ... });
Future<Response> future2 = threadPool.submit(new Callable<>() { ... });
// once you have submitted the last job you can shutdown the pool
threadPool.shutdown();
long start = System.currentTimeMillis();
try {
response1 = future1.get(80, TimeUnit.SECONDS);
} catch (ExecutionException ee) {
// job threw exception
} catch (InterruptedExeception ie) {
// this (main?) thread was interrupted, good pattern to re-interupt
Thread.currentThread().interrupt();
} catch (TimeoutException te) {
// wait timed out, maybe this is right?
response1 = null;
// try to interrupt the thread
future1.cancel(true);
}
// wait for 80 seconds minus how long we've been waiting for 2nd request
long wait = System.currentTimeMillis() - start - 80000;
if (wait < 0) {
wait = 0;
}
try {
response2 = future2.get(wait, TimeUnit.MILLISECONDS);
} catch (ExecutionException ee) {
// job threw exception
} catch (InterruptedExeception ie) {
// this (main?) thread was interrupted, good pattern to re-interrupt
Thread.currentThread().interrupt();
} catch (TimeoutException te) {
// wait timed out, maybe this is right?
response2 = null;
// try to interrupt the thread
future2.cancel(true);
}
这样可以正常工作,但诀窍是打断2个请求。只是中断线程不会杀死任何网络套接字或数据库连接。您必须确保作业可以自行测试中断状态,否则您可能会泄漏线程。