开发者社区 问答 正文

servlet3.0 异步问题 400 请求报错 

用servlet3.0 异步写了一个长链接, 发现 在runnable中的没有结束前, 其他请求线程都在等待中, 怎么阻塞了

@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                //此处 没有立即打印, 要等前一个请求完成后才有反应, 阻塞了 线程
		System.out.println(req.getRequestURL());
		AsyncContext ctx = req.startAsync();
		ctx.setTimeout(14000);
		Executor exec = new Executor(ctx, this);  
		ctx.addListener(new TListener(exec));
		ctx.start(exec);
	}
public static class Executor implements Runnable {
		AsyncContext context;
		HttpServlet servlet;
		boolean isComplete =false; 

		public Executor(AsyncContext context, HttpServlet servlet) {
			this.context = context;
			this.servlet = servlet;
		}

		public void run() {
			HttpServletRequest req = (HttpServletRequest) context.getRequest();
			HttpServletResponse res = (HttpServletResponse) context.getResponse();
			String uri = req.getRequestURI();
			String methodName = uri.substring(uri.lastIndexOf("/"));
			Method method = methods.get(methodName);
			if(method == null){
				context.complete();
				return;
			}
			String query = req.getParameter("query");
			BaseDao service = null;
			if (methodName.indexOf("Result") != -1) {
				service = new TaskResultService();
			}else{
				service = new TaskService();
			}
			
			while (!isComplete) { //此处超时或获取数据会跳出
				Object obj = ServletUtil.invoke(method, servlet, service, query);
				try {
					if (obj != null) {
						ServletUtil.printJSON(res, ServletUtil.toJsonString(obj));
						context.complete();
						return;
					}
					Thread.sleep(3000);
				} catch (Exception e) {
					log.info("Executor:", e);
					context.complete();
					return;
				}
			}
		}
	}

测试发现, 浏览器器 两个请求 先后 上去,  只打印一个 URI, 超时才打印另一个

展开
收起
kun坤 2020-05-30 16:11:52 497 分享 版权
1 条回答
写回答
取消 提交回答
  • servlet3.0 异步本来是为了减少 线程池中的占用 时间, 给予新的线程做处理, 怎么我 写了以后直接把他给堵塞了,  要等待 新线程执行成功才行######准备结贴, google 浏览器 对同一个 url 地址的请求会出现 阻塞的情况, 如果使用刷新就看出来servlet 并没有 堵塞, 可以多个同时请求, 并等待自动回应

    2020-05-30 16:11:57
    赞同 展开评论
问答分类:
问答地址: