我是否允许(没有任何副作用)从servlet的new Thread()
内创建并启动doGet() Method
?或者这会以某种方式泄漏资源?
将“Session
”对象传递给线程以便稍后在会话中保存我的异步处理结果(我会正确同步)是否有效?或者,当使用会话“in indepedant threads”时,这个泄漏会重新获得资源吗?
=>如果会话同时会被webcontainer过期,因为它有timedout并且我将从我的线程访问它会发生什么?或者这也会导致副作用,将会话存储在线程中会阻止web容器到期会话(因此最终会泄漏资源,因为会话没有被清除)?
(我知道还有其他解决方案,比如使用DB-(Job)Records,JMS或Servlets 3.0)但我需要解决问题,如在doGet中跨越一个新线程所描述的那样。)
非常感谢!! 延
答案 0 :(得分:0)
从servlet中创建新线程被认为是不好的做法。产生新线程的常用替代方法是使用JMS / MDB进行异步处理。
答案 1 :(得分:0)
虽然被认为是不好的做法,但它适用于小规模项目。更好的解决方案是使用ExecutorService来执行工作(即使您创建了一个包含ExectorService的单例)。这种方法应该与应用程序服务器提供的线程池一致(尽管我没有尝试过)。
从servlet中执行以下操作:
Future future = myExecutorService.submit(new Task(workRequest));
session.put("result", future);
我也不会将用户Session对象传递给服务,因为会话的实现可能涉及ThreadLocal。而是执行程序生成一个Future对象,您可以将其放入会话中。这样,您可以测试以查看您的异步计算是否稍后完成(或取消或等待它)。
Future future = session.get("result");
boolean isDone = future.isDone();
boolean isCancelled = future.isCancelled();
showInJSP(isDone, isCancelled);
答案 2 :(得分:0)
首先,您想要做的事情将是可行的。取决于一大堆事情。但是如果系统负载很小,请求很少等,它可能会正常工作。
关于您的会话过期问题,赔率是“什么都不会发生”。您将很乐意存储和引用其他人无法查看的信息。
天真地,服务器将使会话到期,并从其内部映射中删除Session对象。与此同时,您的主题将保留对它的引用,并且不会更清楚会话是好还是坏。
在加载的服务器上,系统可能会获取用户会话信息并将其序列化为磁盘。当用户回来时,它会重新读回来。在这种情况下,你将指的是“旧的,孤儿”会话,再次,用户将再也看不到。
当你的线程死亡时,Session将随线程一起离开。
所以,基本上,只要你有一个服务器实例,你没有集群,你的服务器没有交换会话,服务器不会重启(这是另一个点,
。服务器可能会保存和恢复会话,并且会话不会超时 - 你应该很好。是的,这些都是对你的技术的限制,它不会使技术错误,它只是限制了实现。如果您的应用程序和服务在这些限制条件下可以正常工作,那么您就会很高兴,并且不用担心它。
答案 3 :(得分:0)
我是否允许(没有任何副作用)从servlet的doGet()方法中创建并启动一个新的Thread()?
如果实施得当,这很好。
将“Session”对象传递给线程以便稍后在会话中保存我的异步处理结果(我会正确同步)是否有效?
我不会这样做。而是将Thread
存储在会话中。通过这种方式,您可以随时在需要时将其收回。
如果会话同时会被webcontainer过期,因为它有timedout并且我将从我的线程访问它会发生什么?或者这也会导致副作用,将会话存储在线程中会阻止web容器到期会话(因此最终会泄漏资源,因为会话没有被清除)?
会话将过期(如果您在Thread
中不在其中保留对它的引用,则会GC),但该线程将继续运行,直到从{{返回} 1}}方法。通常的做法是在run()
方法中定期检查你自己(如果线程中断或不中断)(例如,在每个步骤或每1%进度期间一次)。您可以实现HttpSessionBindingListener
以在会话过期时发出中断信号。
run()