同时发送2个帖子请求并等待最多80毫秒的响应

时间:2017-06-14 02:18:40

标签: java multithreading http-post

我正在尝试发送两个帖子请求。两者都应该同时发送(在我下面的当前代码中可能会一个接一个地发送)并且应该等待最多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;
}

}

1 个答案:

答案 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个请求。只是中断线程不会杀死任何网络套接字或数据库连接。您必须确保作业可以自行测试中断状态,否则您可能会泄漏线程。