Java ServletContextListener:Isn';这不是不正确的用法吗?
我正在阅读一篇关于“Servlet3.0中的异步处理支持”(AsynchronousProcessingSupportinServlet3.0)的专家教程。其中包含以下代码段:Java ServletContextListener:Isn';这不是不正确的用法吗?,java,multithreading,jakarta-ee,servlet-3.0,Java,Multithreading,Jakarta Ee,Servlet 3.0,我正在阅读一篇关于“Servlet3.0中的异步处理支持”(AsynchronousProcessingSupportinServlet3.0)的专家教程。其中包含以下代码段: @WebServlet(name="myServlet", urlPatterns={"/slowprocess"}, asyncSupported=true) public class MyServlet extends HttpServlet { public void doGet(HttpServletR
@WebServlet(name="myServlet", urlPatterns={"/slowprocess"}, asyncSupported=true)
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
AsyncContext aCtx = request.startAsync(request, response);
ServletContext appScope = request.getServletContext();
((Queue<AsyncContext>)appScope.getAttribute("slowWebServiceJobQueue")).add(aCtx);
}
}
@WebServletContextListener
public class SlowWebService implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
Queue<AsyncContext> jobQueue = new ConcurrentLinkedQueue<AsyncContext>();
sce.getServletContext().setAttribute("slowWebServiceJobQueue", jobQueue);
// pool size matching Web services capacity
Executor executor = Executors.newFixedThreadPool(10);
while(true)
{
if(!jobQueue.isEmpty())
{
final AsyncContext aCtx = jobQueue.poll();
executor.execute(new Runnable(){
public void run() {
ServletRequest request = aCtx.getRequest();
// get parameteres
// invoke a Web service endpoint
// set results
aCtx.forward("/result.jsp");
}
});
}
}
}
public void contextDestroyed(ServletContextEvent sce) {
}
@WebServlet(name=“myServlet”,urlPatterns={”/slowprocess},asyncSupported=true)
公共类MyServlet扩展了HttpServlet{
public void doGet(HttpServletRequest请求、HttpServletResponse响应){
AsyncContext aCtx=request.startAsync(请求,响应);
ServletContext appScope=request.getServletContext();
((队列)appScope.getAttribute(“slowWebServiceJobQueue”)).add(aCtx);
}
}
@WebServletContextListener
公共类SlowWebService实现ServletContextListener{
public void contextInitialized(ServletContextEvent sce){
队列作业队列=新ConcurrentLinkedQueue();
sce.getServletContext().setAttribute(“slowWebServiceJobQueue”,jobQueue);
//池大小与Web服务容量匹配
Executor Executor=Executors.newFixedThreadPool(10);
while(true)
{
如果(!jobQueue.isEmpty())
{
final AsyncContext aCtx=jobQueue.poll();
executor.execute(新的Runnable(){
公开募捐{
ServletRequest=aCtx.getRequest();
//获取参数
//调用Web服务端点
//设定结果
aCtx.forward(“/result.jsp”);
}
});
}
}
}
公共无效上下文已销毁(ServletContextEvent sce){
}
}
因为这是一篇专家的“这就是如何做到的”文章,我想他们不会写一些愚蠢的代码。
但我无法接受在“contextInitialized()”中有一个“while(true)”循环
@WebServletContextListener
public class SlowWebService implements ServletContextListener, Runnable {
private volatile boolean running;
ExecutorService executor;
Thread runner;
Queue<AsyncContext> jobQueue;
public void contextInitialized(ServletContextEvent sce) {
jobQueue = new ConcurrentLinkedQueue<AsyncContext>();
sce.getServletContext().setAttribute("slowWebServiceJobQueue", jobQueue);
// pool size matching Web services capacity
executor = Executors.newFixedThreadPool(10);
runner = new Thread(this);
runner.start();
}
public void run() {
running = true;
while(running)
{
try {
if(!jobQueue.isEmpty())
{
final AsyncContext aCtx = jobQueue.poll();
executor.execute(new Runnable(){
public void run() {
ServletRequest request = aCtx.getRequest();
// get parameteres
// invoke a Web service endpoint
// set results
aCtx.forward("/result.jsp");
}
});
}
}
catch (InterruptException e) {
}
}
}
public void contextDestroyed(ServletContextEvent sce) {
running = false;
runner.interrupt();
executor.shutdown();
}
}
@WebServletContextListener
公共类SlowWebService实现ServletContextListener,Runnable{
私有化;布尔运行;
执行人服务执行人;
螺纹流道;
队列作业队列;
public void contextInitialized(ServletContextEvent sce){
jobQueue=新的ConcurrentLinkedQueue();
sce.getServletContext().setAttribute(“slowWebServiceJobQueue”,jobQueue);
//池大小与Web服务容量匹配
executor=Executors.newFixedThreadPool(10);
流道=新螺纹(此);
runner.start();
}
公开募捐{
运行=真;
(跑步时)
{
试一试{
如果(!jobQueue.isEmpty())
{
final AsyncContext aCtx=jobQueue.poll();
executor.execute(新的Runnable(){
公开募捐{
ServletRequest=aCtx.getRequest();
//获取参数
//调用Web服务端点
//设定结果
aCtx.forward(“/result.jsp”);
}
});
}
}
捕获(中断异常){
}
}
}
公共无效上下文已销毁(ServletContextEvent sce){
运行=错误;
runner.interrupt();
executor.shutdown();
}
}
2) 只要其他servlet具有不同的urlPattern,它们就不会受到影响。此代码不会在contextDestroyed上清除,也不会停止运行。“执行器”由“runner”线程和“context listener事件处理”线程访问。它是否应该是易变的或以某种方式同步的?我想将“running”设置为false并“interrupt”线程的原因是为了强制线程退出其“poll”,并让它查看是否应该继续“running”。是吗?@vendhan是的,是的,否则当上下文被破坏时线程不会停止。在这种情况下,您不需要同步执行器。同意在引用后不需要同步执行器,但令人难以置信的是,规范中没有正确记录这一点!你能回答问题2吗?所以我可以选择这个作为答案。