我刚开始阅读Core JavaServer Faces,第3版.他们这样说(强调我的):
对于可以在JSF页面中使用的bean,有两种不同的机制,CDI bean和JSF托管bean,这是一个历史事故.我们建议您使用CDI bean,除非您的应用程序必须在像Tomcat这样的普通servlet运行器上运行.
为什么?他们没有提供任何理由.我一直在使用@ManagedBean在GlassFish 3上运行的原型应用程序中的所有bean,我还没有发现任何问题.我不介意迁移@ManagedBean到@Named,但我想知道为什么我应该打扰.
据我所知,Java Servlets同时处理多个请求,我搜索了StackOverflow以及Google,并确认了我的想法.但是我现在很困惑,我写了一个似乎显示阻塞行为的简单servlet.
所以我有一个简单的Servlet:
public class MyServlet extends HttpServlet
{
private static final long serialVersionUID = 2628320200587071622L;
private static final Logger logger = Logger.getLogger(MyServlet.class);
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
logger.info("[doGet] Test before");
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logger.info("[doGet] Test after");
resp.setContentType("text/plain");
resp.getWriter().write("OK");
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有2个浏览器窗口,我同时打开了我的Servlet.结果是第一个请求阻止第二个请求.日志还显示:
10:49:05,088 [http-8383-Processor14] INFO MyServlet - [doGet] Test before
10:50:05,096 [http-8383-Processor14] INFO MyServlet - [doGet] Test after
10:50:05,106 [http-8383-Processor22] INFO MyServlet …Run Code Online (Sandbox Code Playgroud) 我一直在谷歌搜索几个小时在这个问题上没有评估.
关于所提供示波器的线程安全性,WELD文档和CDI规范非常明确.
例如:
适用范围 - 不安全
会话范围 - 不安全
请求范围 - 安全,始终绑定到单个线程
会话范围 - 安全(由于WELD代理序列化来自多个请求线程的访问)
我在JSF 2.x定义的View Scope上找不到任何东西.
它与对话范围大致相同,因为尽管绑定到单个视图/用户,但多个请求很可能同时命中范围.我不知道的是JSF实现是否从多个请求序列化对bean的访问.
任何人都知道规格或Morraja/MyFaces的实施可以解决这个问题吗?
我们的生产环境中存在一个问题,4个线程在HTOP命令中处于100%CPU使用率.为了进一步研究这个问题,我生成了一个Thread转储,以便找到正在吃CPU的线程.
这是我发现的.4个线程具有相同的堆栈跟踪,所有这些都处于RUNNABLE状态.不幸的是,我陷入了调查,因为堆栈跟踪没有引用我的内部代码,它更多地在Richfaces方面.我认为这是JSF呈现页面的部分.
堆栈跟踪.
"ajp-0.0.0.0-8009-47" daemon prio=10 tid=0x00007fb8040af000 nid=0x172c runnable [0x00007fb8b3bf8000]
java.lang.Thread.State: RUNNABLE
at java.util.HashMap.hash(HashMap.java:351)
at java.util.HashMap.putForCreate(HashMap.java:512)
at java.util.HashMap.putAllForCreate(HashMap.java:534)
at java.util.HashMap.<init>(HashMap.java:320)
at org.ajax4jsf.component.UIDataAdaptorBase.createChildStateCopy(UIDataAdaptorBase.java:894)
at org.ajax4jsf.component.UIDataAdaptorBase.saveState(UIDataAdaptorBase.java:1554)
at org.richfaces.component.UIDataTable.saveState(UIDataTable.java:181)
at org.richfaces.component.html.HtmlDataTable.saveState(HtmlDataTable.java:1361)
at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1103)
at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
at org.ajax4jsf.component.AjaxViewRoot.processSaveState(AjaxViewRoot.java:751)
at org.ajax4jsf.application.AjaxStateManager.getComponentStateToSave(AjaxStateManager.java:179)
at org.ajax4jsf.application.AjaxStateManager.buildViewState(AjaxStateManager.java:515)
at org.ajax4jsf.application.AjaxStateManager$SeamStateManagerWrapper.saveView(AjaxStateManager.java:106)
at org.jboss.seam.jsf.SeamStateManager.saveView(SeamStateManager.java:89)
at org.ajax4jsf.application.AjaxStateManager.saveSerializedView(AjaxStateManager.java:470)
at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:615)
at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.josso.servlet.agent.GenericServletSSOAgentFilter.doFilter(GenericServletSSOAgentFilter.java:558)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) …Run Code Online (Sandbox Code Playgroud) Java EE 规范的 Servlet、EJB 和 CDI 部分描述了 bean 管理(注入等)。但是规范也没有描述(显式或隐式)bean 容器的并发属性。如果我使用了 WildFly 或 GlassFish,那么 Java EE 应用服务器可以从一个线程访问更多的 bean 对象。
所以问题是,我是否必须对volatile所有 bean 字段使用关键字,理论上可以从多个线程访问(即对于几乎所有 bean,至少对于所有用 注释的字段@Inject)?
cdi ×3
jsf ×3
concurrency ×2
java ×2
jsf-2 ×2
ejb ×1
jakarta-ee ×1
java-ee ×1
javabeans ×1
servlets ×1
view-scope ×1
volatile ×1